Skip to content
🎁
tuvix.js
tuvix.js (paquete paraguas)
Un paquete, una ruta de importación. Reexporta el orquestador de @tuvix.js/core y las APIs públicas de @tuvix.js/router, @tuvix.js/event-bus, @tuvix.js/loader y @tuvix.js/sandbox.

Instalación ​

bash
npm install tuvix.js
# or pnpm add tuvix.js

Instalar tuvix.js instala @tuvix.js/core, @tuvix.js/router, @tuvix.js/event-bus, @tuvix.js/loader y @tuvix.js/sandbox. Los seis paquetes incluyen builds de ES module y CommonJS y declaran "sideEffects": false.

Cuándo usarlo ​

Instala tuvix.js en una aplicación shell que usa el orquestador junto con el router, el event bus o el sandbox. Tienes una sola dependencia que versionar y una sola ruta de importación, y tu bundler descarta los exports que nunca importas.

Instala en su lugar los paquetes con scope cuando:

  • Una micro app solo se comunica con la shell. @tuvix.js/event-bus por sí solo le da getGlobalBus(), sin meter el orquestador en su node_modules.
  • Necesitas un export que el paquete paraguas deja fuera, como registerModule o emitLifecycle de @tuvix.js/loader, o pathToRegex de @tuvix.js/router. Consulta No incluido.
  • Quieres que tu package.json indique de qué partes de Tuvix.js depende un paquete.

Combinar ambos es seguro. El paquete paraguas reexporta los mismos módulos, así que getGlobalBus de tuvix.js y de @tuvix.js/event-bus devuelven el mismo bus, y los helpers de ciclo de vida comparten un registro en window.

Inicio rápido ​

Una shell que monta about en /about, convierte los clics en enlaces en navegaciones del router y registra los errores de las apps:

ts
import { createOrchestrator, getGlobalBus, interceptLinks, OrchestratorEvent, type AppErrorEvent } from 'tuvix.js';

const orchestrator = createOrchestrator({ router: { routes: [] } });

orchestrator.register({
  name: 'about',
  entry: 'https://cdn.example.com/about/main.js',
  container: '#main',
  activeWhen: '/about',
  props: { who: 'us' },
});

getGlobalBus().on<AppErrorEvent>(OrchestratorEvent.APP_ERROR, ({ name, error, phase }) => {
  console.error(`${name} failed during ${phase}`, error);
});

await orchestrator.start();
interceptLinks({ navigate: (path) => orchestrator.navigateTo(path) });

La app about, compilada en https://cdn.example.com/about/main.js:

ts
import { defineMicroApp } from 'tuvix.js';

export default defineMicroApp({
  name: 'about',
  mount({ container, props }) {
    container.innerHTML = `<h1>About ${String(props?.who)}</h1>`;
  },
  unmount({ container }) {
    container.replaceChildren();
  },
});

Al hacer clic en <a href="/about?ref=nav"> se añade /about?ref=nav al historial, y el orquestador monta about en #main (la query string no afecta a la coincidencia).

API ​

Todos los exports siguientes son reexportaciones. La página del paquete enlazado documenta su firma, sus opciones y sus casos límite.

Desde @tuvix.js/core ​

Documentación: @tuvix.js/core.

ExportTipoQué hace
createOrchestratorfunciónCrea un Orchestrator.
OrchestratorclaseRegistra apps, las reconcilia con la URL, sigue a un router (connectRouter), actualiza props y destruye.
defineMicroAppfunciónValida un objeto { name, bootstrap?, mount, unmount, update?, ssr? }, lo registra para el loader y hace que emita tuvix:mounted / tuvix:unmounted / tuvix:error.
OrchestratorEventenumNombres de los eventos que el orquestador emite en su bus (tuvix:app:mount, tuvix:app:error, ...).
OrchestratorConfig, MicroAppConfig, MicroAppDefinitiontipoArgumentos de createOrchestrator, register y defineMicroApp.
AppStatus, AppSandboxOption, RouterSource, RegisteredApptipoUnión de estados de una app, la opción sandbox, el argumento de connectRouter y la forma del registro de una app.
AppErrorEvent, AppErrorPhasetipoPayload de APP_ERROR { name, error, phase } y su unión de fases ('load', 'bootstrap', 'mount', 'update', 'unmount').

Desde @tuvix.js/event-bus ​

Documentación: @tuvix.js/event-bus.

ExportTipoQué hace
EventBusclaseBus pub/sub con on, once, emit, off, onAny.
createEventBusfunciónCrea un EventBus nuevo e independiente.
getGlobalBusfunciónDevuelve el bus de toda la página guardado en window.__TUVIX_GLOBAL_BUS__. El orquestador lo usa por defecto.
resetGlobalBusfunciónDestruye el bus de toda la página; el siguiente getGlobalBus() crea uno nuevo.
IEventBus, EventHandler, WildcardHandler, Unsubscribe, EventBusOptionstipoInterfaz del bus, firmas de los handlers, función para cancelar la suscripción y opciones del constructor.

Desde @tuvix.js/router ​

Documentación: @tuvix.js/router.

ExportTipoQué hace
RouterclaseRouter de history o hash que asocia rutas a nombres de apps.
createRouterfunciónCrea un Router.
matchPathfunciónCompara una ruta con un patrón (:param, /*; ignora la query y el hash). Las cadenas de activeWhen lo usan.
matchRoutefunciónDevuelve la primera ruta de un RouteConfig[] que coincide por completo con una ruta, con params y query.
normalizePathfunciónAñade una barra inicial y elimina la final.
interceptLinksfunciónConvierte los clics en enlaces del mismo origen en una llamada a navigate(path), con precarga opcional por intención.
resolveLinkfunciónDevuelve { anchor, url, path } para el enlace HTML en el que ocurrió un evento, o null cuando el navegador debe gestionarlo.
IRouter, RouterConfig, RouterMode, RouteConfig, MatchedRoutetipoInterfaz del router, opciones y formas de las rutas.
NavigationEvent, NavigationGuard, RouteChangeHandlertipoPayload de navegación y firmas del guard y del listener.
PathMatch, MatchPathOptions, InterceptLinksOptions, ResolvedLink, ResolveLinkOptionstipoResultado y opciones de matchPath, opciones de interceptLinks, resultado y opciones de resolveLink.

Desde @tuvix.js/loader ​

Documentación: @tuvix.js/loader.

ExportTipoQué hace
ModuleLoaderclaseCarga una entry (URL, configuración de scripts y estilos o función loader) con timeout, reintentos y caché.
createLoaderfunciónCrea un ModuleLoader.
whenMountedfunciónResuelve cuando una app emite su evento de ciclo de vida mounted.
onLifecyclefunciónEscucha los eventos del DOM tuvix:mounted, tuvix:unmounted o tuvix:error.
isMountedfuncióntrue mientras algún contenedor de la app esté montado, según los eventos de ciclo de vida.
Entry, EntryConfig, MicroAppModule, MountContext, UnmountContext, UpdateContexttipoFormatos de entry y el contrato de ciclo de vida que implementa una micro app.
LoaderOptions, LoadResult, LoadStatus, PrefetchStrategytipoOpciones y resultados del loader.
LifecycleType, LifecycleDetail, LifecycleEventtipoNombres de los eventos de ciclo de vida, payload y tipo de evento del DOM.
ts
import { onLifecycle, whenMounted } from 'tuvix.js';

const off = onLifecycle('error', ({ name, error }) => console.error(name, error));

const { container, hydrated } = await whenMounted('footer', { signal: AbortSignal.timeout(5000) });
console.log(container.id, hydrated);
off();

Desde @tuvix.js/sandbox ​

Documentación: @tuvix.js/sandbox.

ExportTipoQué hace
CssSandboxclaseMueve un contenedor a un shadow root y carga hojas de estilos dentro de él. El orquestador lo usa para sandbox: true.
JsSandboxclasewindow Proxy que mantiene los globals que escribe un script fuera del window real.
SandboxclaseCssSandbox y JsSandbox detrás de un único par activate / deactivate.
createSandboxfunciónCrea un Sandbox.
SandboxOptions, ISandbox, ICssSandbox, IJsSandboxtipoOpciones e interfaces de los sandboxes.
AdoptStylesOptions, AdoptedStylestipoArgumento y valor de retorno de CssSandbox.adoptStyles.

No incluido ​

El paquete paraguas deja fuera lo siguiente. Instala el paquete que lo proporciona.

NecesitasInstala
registerModule, unregisterModule, getRegisteredModule, emitLifecycle, hasServerMarkup, normalizeEntry, loadScript, loadStyle, removeScript, removeStyle, prefetchResource, y los tipos EntryLoader, EntryLoaderContext, MicroAppBus, ScriptType, CacheEntry, ResourceOptions, LoadScriptOptions, LoadStyleOptions, PrefetchOptions@tuvix.js/loader
pathToRegex, parseQuery, isPathActive@tuvix.js/router
Micro apps de React, Vue, Svelte o Angular@tuvix.js/react, @tuvix.js/vue, @tuvix.js/svelte, @tuvix.js/angular
Composición en el servidor@tuvix.js/server
Remotes de Module Federation@tuvix.js/module-federation
Assets de islas en builds de Vite@tuvix.js/vite
El panel de DevTools@tuvix.js/devtools
Scaffolding de proyectoscreate-tuvix-app

Casos límite ​

  • tuvix.js tiene un único punto de entrada. Los imports de subrutas como tuvix.js/core o tuvix.js/router no se resuelven; importa desde tuvix.js o desde el paquete con scope.
  • El paquete paraguas fija sus dependencias a la misma versión. Instalar tuvix.js junto a otra versión de un paquete con scope te deja dos copias de ese paquete. getGlobalBus() y el registro de ciclo de vida siguen compartiendo estado a través de window, pero las comprobaciones instanceof Orchestrator o instanceof EventBus fallan entre copias.
  • whenMounted, onLifecycle e isMounted reaccionan a los eventos del DOM tuvix:*. Los módulos de defineMicroApp y los adaptadores de frameworks los emiten; un módulo escrito a mano no emite ninguno salvo que llame a emitLifecycle de @tuvix.js/loader. Los eventos de un contenedor que está fuera del documento se despachan en document.
  • resetGlobalBus() destruye el bus que tiene un orquestador en ejecución. El orquestador conserva ese bus destruido, así que sus eventos ya no llegan a los suscriptores del siguiente getGlobalBus(). Llámalo entre tests, después de orchestrator.destroy().
  • Los cambios de comportamiento y los cambios incompatibles de @tuvix.js/core y @tuvix.js/router se aplican aquí sin cambios. Consulta Migrar desde 0.4.

Lo que no hace ​

  • No añade código propio. Cada export viene de uno de los cinco paquetes con scope.
  • No incluye los adaptadores de frameworks, el paquete de servidor, Module Federation, Vite ni DevTools.
  • No ofrece entradas de subruta por paquete.