Modelo documental
Estructura versionada con Unicode, bus de comandos y undo/redo. El estado vivo es JSON, no el DOM.
Una suite ofimática construida desde cero: modelo documental en Rust,
puente WebAssembly, interfaz React 19 y servicios Go.
Un monorepo que avanza por fases y migra sus propios formatos en cada una.
Conviene decirlo antes que nada, porque la página cuenta lo que ya existe y es fácil confundir un repositorio activo con un producto terminado.
0.7.0-phase.2.5: se instala clonando el repositorio y levantándolo en
local.
SECURITY.md.schema v5
y cada versión trae su migración automática desde las anteriores, pero sigue en
movimiento.Rhino Suite se construye desde el modelo hacia afuera: primero un modelo documental estructurado e independiente de la plataforma, y sobre él la interfaz, la persistencia y el intercambio de formatos. No al revés.
El editor de documentos ya es funcional y vive dentro de una unidad de archivos con cuentas: cada persona entra con su correo, ve solo lo suyo y puede compartir documentos. Hoja de cálculo, presentaciones, PDF, colaboración en tiempo real y escritorio llegan en fases posteriores sin romper lo anterior.
Regla central: las reglas del documento no dependen del DOM, de React ni del sistema operativo. El HTML nunca es el estado vivo — solo una proyección del JSON versionado.
Todo lo de esta lista está entregado y cubierto por la Fase 2.5. Nada de lo que viene después aparece aquí.
Estructura versionada con Unicode, bus de comandos y undo/redo. El estado vivo es JSON, no el DOM.
Selección multipárrafo, estilos, listas, tablas, imágenes y portapapeles propio con MIME semántico.
Secciones, columnas, encabezados, pies, campos dinámicos y numeración independiente por sección.
Comentarios con respuestas y resolución, marcadores e hipervínculos anclados al modelo, y control de cambios con autor, estado e instantáneas reversibles.
Busca en cuerpo, tablas, encabezados, pies y comentarios — sobre el modelo, no sobre el texto renderizado.
Vista de impresión con hoja de estilos dedicada y paginación A4 calculada por el motor.
Importación y exportación inicial con lector/escritor ZIP y XML OOXML/ODF propios, sin dependencias externas.
Una instantánea por guardado (se conservan las 40 últimas). Restaurar deja lo anterior como revisión nueva, así que también se puede deshacer.
Carpetas, recientes, destacados, papelera con restauración, búsqueda, orden, selección múltiple con acciones en lote, arrastrar y soltar y subida de DOCX/ODT.
Alta y entrada con correo y contraseña (Argon2id + cookie de sesión HttpOnly). Cada persona ve solo sus documentos y los comparte con permiso de lectura o edición.
/document/<id>: recargar vuelve al mismo sitio, el botón atrás
funciona y un documento se puede marcar o compartir por enlace.
Tema claro y oscuro, idioma español e inglés, y ajustes accesibles desde la propia aplicación.
Tres lenguajes con un contrato en JSON entre ellos. Rust es la implementación principal del motor; TypeScript mantiene un motor compatible para poder desarrollar sin instalar Rust.
| Capa | Tecnología |
|---|---|
| Interfaz | React 19 · TypeScript · Vite |
| Motor principal | Rust (crates/office-core) |
| Puente navegador | WebAssembly · wasm-bindgen (crates/office-wasm) |
| Motor compatible | TypeScript (packages/engine-client, respaldo de desarrollo) |
| Servicios | Go net/http · única dependencia: golang.org/x/crypto |
| Cuentas | Argon2id · sesión en cookie HttpOnly |
| Persistencia local | IndexedDB (copia offline) |
| Intercambio | OOXML/ODF + ZIP implementados en el propio repositorio |
| Monorepo | pnpm · Cargo · Go workspace |
Cada fase conserva las anteriores y tiene una puerta de salida verificable. No se empieza una fase dependiente sin cumplir la puerta de la anterior. Estás aquí → Fase 2.5.
Monorepo pnpm/Cargo/Go, modelo versionado, bus de comandos, undo/redo, WASM y API inicial.
Edición rica, secciones, revisión, impresión, DOCX/ODT y —en la 2.5— unidad de archivos, cuentas y compartición.
Libro y hoja, cuadrícula virtualizada, fórmulas con recálculo incremental, filtros, gráficos y XLSX/CSV/ODS.
Grafo de escena 2D: diapositivas, formas, capas, temas, transiciones y PPTX/ODP inicial.
Parser de objetos y xref, renderizado, anotaciones y formularios, escritura incremental.
CRDT, WebSocket, presencia y cursores remotos. Los permisos y el historial ya se adelantaron en la 2.5.
Tauri 2: asociaciones de archivo, guardado atómico, recuperación ante fallos y actualizaciones firmadas.
OOXML/ODF ampliados, round-trip automatizado, rendimiento medido, fuzzing y auditoría.
La subfase 2.5 nació de usar el producto, no del plan: sin un sitio donde encontrar los documentos ni cuentas que los separen, el editor no era utilizable de verdad. Al hacerla se adelantó la compartición con permisos, que estaba en la Fase 6; esa fase queda ahora acotada a lo difícil de verdad — que dos personas escriban a la vez sin pisarse.
No hay instaladores: se levanta en local desde el repositorio. Requisitos mínimos
Node ≥ 22 y pnpm 11; para el motor Rust/WASM y la API Go
hacen falta además Rust stable con el target wasm32-unknown-unknown, wasm-pack y
Go 1.23.
La forma más corta, sin instalar Rust ni Go. Levanta web y API juntas.
# web en http://localhost:8088
docker compose up -d --build
La primera cuenta que se registra adopta los documentos que existieran antes de haber cuentas.
Usa el motor TypeScript de respaldo, así que no requiere la cadena de Rust.
pnpm install
pnpm dev
# API Go opcional (persistencia de documentos)
pnpm dev:api
Un smoke test del editor con 20 aserciones y sin dependencias externas.
npx tsx scripts/validate-phase24.ts
Typecheck, tests TypeScript y Go, build web, tests de Rust y compilación WASM.
# solo TS + Go + build web
pnpm check
# todo, incluido Rust y WASM
pnpm check:full
Cada push y cada PR pasan por tres workflows en GitHub Actions.
CI typecheck · tests TS · build web
cargo fmt/clippy/test · build WASM
go vet · go test -race · build
Security Scan CodeQL (JS/TS) · Trojan Source
govulncheck · cargo-audit
Workflow security actionlint · zizmor · pin a SHA
Todo vive en docs/ y tiene su mapa de navegación en el índice. Estos son los
puntos de entrada frecuentes.