@js-maia/ui
v2.0.1
Published
MAIA-UI: Gestor completo del frontend para el ecosistema MAIA
Maintainers
Readme
@js-maia/ui — MAIA-UI
Módulo Anillo 2 — MAIA-Systems (remoto) del ecosistema MAIA. Gestiona la interfaz de usuario: servidor HTTP (Hono + SSE), registro de ítems UI en zonas predefinidas, SPA React y carga dinámica vía Module Federation.
El Core instala @js-maia/ui por npm (org npm js-maia), spawn el binario maia-ui y orquesta el lifecycle (init → start → shutdown) por WebSocket. MAIA-UI no implementa IModule ni depende de @maia/core.
Nomenclatura: paquete npm
@js-maia/ui· org npmjs-maia·moduleIddel protocolo MAIA:maia-ui· anillo: 2 (Systems). Taxonomía canónica: .Docs/Architecture/SpecsDocs/MAIA-RINGS/README.md.
Arquitectura (resumen)
Core (Anillo 0) ──HTTP register + WS lifecycle──► MAIA-UI (Anillo 2, proceso Bun)
Anillo 3+ ──register-item vía Core────────► slots + remoteUrl (Module Federation)
Navegador ──HTTP/SSE──────────────────────► UI_PORT (3100) + ui/public/distDiagrama interactivo: .Docs/Architecture/Diagram/ · Specs acordadas: .Docs/Architecture/SpecsDocs/.
Estructura del repositorio (v2.0)
Layout piloto Roadmap 2 — taxonomía MC / ms / ma:
src/
app/components/MCAppHost/ # Proceso: bin, WS al Core, maRunMaiaUi
ui/components/
MCHandlers/ # Lifecycle + requests + SSE
MCUiServer/ # Hono, estáticos ui/public/dist
MCUiState/ # Zonas e ítems registrados
MCUiLayout/ # Elementos shell (layout, slot, MF)
MCUiSpa/ # Runtime React + Vite (tooling en raíz MC)
__tests__/<MCName>/ # Tests espejo por MComponent
shared/ms-config.ts # Variables de entorno
server/index.ts # Facade @js-maia/ui/server
index.ts # Entry npm / maia-ui
ui/public/dist/ # SPA producción (build:client)| MC* | Responsabilidad |
| --- | --------------- |
| MCAppHost | CLI, registro HTTP, cliente WS, wire de handlers |
| MCHandlers | init/start/…, topics maia-ui.*, broadcast SSE |
| MCUiServer | HTTP :UI_PORT, /health, /events, /api/state |
| MCUiState | registerItem, zonas, preferencias |
| MCUiLayout | UiLayout, Zone, Slot, ModuleLoader |
| MCUiSpa | App React, hooks, Module Federation |
Instalación y consumo desde el Core
{
"dependencies": {
"@js-maia/ui": "^2.0.0"
}
}Arranque (spawn, no import in-process):
CORE_URL=http://localhost:3000 MAIA_AUTH_TOKEN=<token> node_modules/.bin/maia-ui
# o
bunx maia-uiManifiesto npm (package.json → maia):
{ "integration": "remote", "ring": 2, "moduleId": "maia-ui" }| Subpath | Uso |
|---------|-----|
| @js-maia/ui | CLI / bin (maia-ui) |
| @js-maia/ui/server | API programática (tests, herramientas) |
| @js-maia/ui/types | Tipos de dominio UI (módulos Anillo 3+ / Services) |
Fallback file: (solo dev local del Core, no CI/producción): "@js-maia/ui": "file:../MAIA-UI".
Launcher remoto y E2E Core↔UI: repo Core-AsistenteIA.
Detalle del paquete: .Docs/Architecture/SpecsDocs/MAIA-Modules/MAIA-UI/MAIA-UI-Package.md.
Variables de entorno
| Variable | Descripción | Por defecto |
|----------|-------------|-------------|
| CORE_URL | URL HTTP del Core (registro + WS) | http://localhost:3000 |
| MAIA_AUTH_TOKEN | Bearer para POST /modules/register | — (requerido en runtime) |
| UI_PORT | Puerto HTTP tras lifecycle start | 3100 |
| LOG_LEVEL | Nivel de log (debug, info, warn, error) | info |
| FRONTEND_DEV_PORT | Puerto Vite en bun run dev:client | 5173 |
Copia .env.example → .env para desarrollo local.
Comandos lifecycle (Core → MAIA-UI)
Enviados por WebSocket como { "type": "command", "commandId": "<uuid>", "command": "<name>" }. MAIA-UI responde con { "type": "response", "commandId": "...", "status": "ok" \| "error", "data"?, "error"? }.
| Comando | Fase tras OK | Descripción |
|---------|--------------|-------------|
| init | initialized | Resetea estado interno; no levanta HTTP |
| start | active | Arranca Hono en UI_PORT y sirve ui/public/dist |
| shutdown | shutting_down | Detiene HTTP, limpia SSE/estado, cierra WS y termina el proceso |
| health | — | Devuelve HealthStatus (Core WS + servidor HTTP) |
Ejemplo — start:
{ "type": "command", "commandId": "cmd-001", "command": "start" }{
"type": "response",
"commandId": "cmd-001",
"status": "ok",
"data": { "port": 3100, "running": true }
}Comandos
ui.*(ui.navigate,ui.theme, …) están en la especificación del protocolo pero aún no están implementados en este release; usa los request topicsmaia-ui.routeymaia-ui.notify.
Request topics (otros módulos → MAIA-UI vía Core)
Enrutados al módulo maia-ui con { "type": "request", "requestId": "<uuid>", "topic": "...", "payload": {...} }.
| Topic | Payload | Respuesta data | Efecto |
|-------|---------|------------------|--------|
| maia-ui.register-item | item, moduleId, slot, remoteUrl, metadata? | { registered, slotId, position } | Registra ítem en zona; broadcast SSE |
| maia-ui.unregister-item | item, moduleId | { unregistered: true } | Elimina ítem |
| maia-ui.notify | message, type?, timeout? | { displayed: true } | Notificación → clientes SSE |
| maia-ui.route | route, params? | { routed: true } | Navegación → clientes SSE |
| maia-ui.get-state | — | snapshot UI | Estado actual (zonas, tema) |
Zonas (slot): header (1), sidebar (5), main (1), footer (1), modal (10).
Ejemplo — registrar panel remoto:
{
"type": "request",
"requestId": "req-100",
"from": "maia-chat",
"topic": "maia-ui.register-item",
"payload": {
"item": "ChatPanel",
"moduleId": "maia-chat",
"slot": "sidebar",
"remoteUrl": "http://localhost:3200/assets/remoteEntry.js",
"metadata": { "displayName": "Chat", "priority": 1 }
}
}{
"type": "response",
"requestId": "req-100",
"status": "ok",
"data": { "registered": true, "slotId": "sidebar-1", "position": 1 }
}Eventos y topics
Eventos del Core reenviados a navegadores (SSE)
MAIA-UI reenvía al stream /events los mensajes { "type": "event", "topic", "payload" } que el Core envía por WebSocket (p. ej. system.*, module.*). Ver Protocolo §10.1.
Eventos SSE emitidos por MAIA-UI (handlers internos)
| Topic SSE | Origen | Descripción |
|-----------|--------|-------------|
| maia-ui.item-registered | register-item | Ítem añadido a una zona |
| maia-ui.item-unmounted | unregister-item | Ítem eliminado |
| maia-ui.notify | maia-ui.notify | Notificación para la UI |
| maia-ui.navigation | maia-ui.route | Cambio de ruta solicitado |
Publicación al EventBus del Core (
type: "publish", p. ej.maia-ui.client-connected) está prevista en el protocolo pero no implementada aún; los clientes web usan SSE enUI_PORT.
API HTTP (navegador / herramientas)
Disponible tras lifecycle start:
| Método | Ruta | Descripción |
|--------|------|-------------|
| GET | /health | Estado del servicio e ítems registrados |
| GET | /api/state | Snapshot JSON de zonas y preferencias |
| GET | /events | Stream SSE (text/event-stream) |
| POST | /api/request | Proxy opcional al Core (target, topic, payload) |
| GET | /* | SPA estática desde ui/public/dist |
Ejemplo — estado:
curl http://localhost:3100/api/stateModule Federation — integrar UI desde otros módulos
Los módulos Ring 2+ exponen exports React como remotes de Vite Federation y los registran como ítems en MAIA-UI.
1. En el módulo remoto (ej. @maia/chat)
vite.config.ts:
import federation from '@originjs/vite-plugin-federation';
export default defineConfig({
plugins: [
react(),
federation({
name: 'maia_chat',
filename: 'remoteEntry.js',
exposes: { './ChatPanel': './src/ChatPanel.tsx' },
shared: ['react', 'react-dom'],
}),
],
server: { port: 3200, cors: true },
});2. Registrar en MAIA-UI (vía Core)
Request maia-ui.register-item con:
slot: zona destino (sidebar,main, …)remoteUrl: URL delremoteEntry.jsaccesible desde el navegadoritem: nombre del export expuesto en el remote (ChatPanel)
3. Render en el shell MAIA-UI
El frontend usa ModuleLoader (src/ui/components/MCUiLayout/ms-module-loader.tsx): carga remoteUrl, extrae itemName y monta el ítem en el Slot de la zona.
4. Desregistrar
Request maia-ui.unregister-item con moduleId + item.
Requisitos: CORS en el remote, shared alineado (React 18), URL estable en producción. Tipos compartidos: @js-maia/ui/types.
Ejemplos de arranque y comunicación
Desarrollo — CLI con Core real:
bun install && cp .env.example .env
# Terminal 1: Core en CORE_URL
# Terminal 2:
bun run dev
# El Core debe enviar init → start por WSSolo frontend (sin lifecycle):
bun run dev:client # http://localhost:5173Request al Core desde el servidor UI (tras start, WS abierto):
import { sendRequestToCore } from '@js-maia/ui/server';
const data = await sendRequestToCore('maia-dbls', 'dbls.get', { key: 'theme' });Proxy HTTP desde el navegador (requiere sendRequest configurado en runtime):
curl -X POST http://localhost:3100/api/request \
-H 'Content-Type: application/json' \
-d '{"target":"maia-auth","topic":"token:validate","payload":{"token":"..."}}'Checklist smoke manual
- Core en marcha; instalar
@js-maia/uidesde npm semver o tarball (npm pack). CORE_URL=... MAIA_AUTH_TOKEN=... maia-ui→ registro HTTP + WS OK.- Core envía
init→start. GET http://localhost:3100/healthy/api/stateresponden OK.- Opcional:
maia-ui.register-itemy verificar/api/state. shutdown→ proceso termina.
Tarball: bun run verify:pack.
Publicación npm (consumo desde Core)
El paquete publicado incluye dist/ (CLI + servidor) y ui/public/dist/ (SPA React precompilada). El Core no debe compilar en postinstall. El tarball no incluye src/, tests ni .Docs/.
| Script | Qué builda | Cuándo |
|--------|------------|--------|
| bun run build | Servidor + bin + tipos (dist/) | Desarrollo backend / tests rápidos |
| bun run build:client | SPA React → ui/public/dist/ | Solo frontend |
| bun run build:all | Módulo completo (cliente + servidor) | Release npm — prepublishOnly |
| bun run pack | build:all + npm pack | Probar tarball local |
| bun run verify:pack | build:all + test del tarball + install limpio | CI / pre-release |
Probar instalación limpia (como Core):
bun run verify:pack
# genera js-maia-ui-2.0.1.tgz en la raíz
cd ../Core-AsistenteIA
bun add ../MAIA-UI/js-maia-ui-2.0.1.tgz
bun run modules:verifyPublicar:
bun run build:all
npm publish --access public --otp=CODIGO_2FA
git tag v2.0.1 && git push origin v2.0.1Notas:
preparesolo instala Husky en este repo (clon con.git); no corre al instalar@js-maia/uicomo dependencia.- Hono sirve estáticos desde ruta absoluta al paquete (
ui/public/dist), no depende delcwddel Core al hacer spawn. - Variables runtime:
CORE_URL,MAIA_AUTH_TOKEN,UI_PORT(ver.env.example). - Sin
@maia/coreen runtime — solo HTTP + WebSocket. - 2.0.0 breaking: topics/payloads
item(sin alias*-component). Handoff Core: .Docs/Roadmaps/Core-Handoff-MAIA-UI-2.0.md.
Scripts de desarrollo
| Script | Descripción |
|--------|-------------|
| bun run dev | CLI → Core real |
| bun run dev:client | Frontend Vite aislado |
| bun run build | Servidor + tipos (dist/) |
| bun run build:all | Módulo completo — release npm (prepublishOnly) |
| bun run check | typecheck + ESLint |
| bun run check:ci | check + test + verify:pack (gate CI) |
| bun run test | Unitarios + integración (WS mock) |
| bun run test:coverage | Cobertura |
| bun run verify:pack | build:all + test tarball |
| bun run verify:ecosystem | modules:verify en Core (MAIA_CORE_ROOT) |
Requisito: Bun ≥ 1.0.
Testing
- Tests en espejo MC*:
src/app/components/__tests__/MCAppHost/,src/ui/components/__tests__/<MCName>/(integración mock enMCHandlers/integration.test.ts). - E2E con Core real: Core-AsistenteIA.
Referencias
Arquitectura (specs canónicas)
- Modelo de anillos (MAIA-RINGS)
- Visión de producto
- Definición de módulo MAIA
- Componentes internos (MAIA-COMPONENT)
- Diagrama interactivo (MAIA Brain)
- Guía de integración de módulos
