Core, subsistemas y manifests
Elige entradas opcionales y declara el contrato de cada app desde un archivo, el shell o su módulo.
Esta página describe WU Framework 4.0.0. Consulta la migración a Framework 4.0 y CLI 1.2 antes de actualizar un proyecto existente.
Elegir el runtime
wu-framework carga sus subsistemas opcionales al primer uso. wu-framework/core requiere imports explícitos en el shell. La CLI 1.0.0 comparte la entrada core entre el shell y las apps, tanto en desarrollo como en producción.
import { wu } from 'wu-framework/core';
import 'wu-framework/timeline';
import 'wu-framework/ports';
await wu.init({ apps: [] });
const timeline = await wu.timelineReady();
| Función | Import del shell |
|---|---|
| AI | wu-framework/ai |
| Timeline | wu-framework/timeline |
| Devtools | wu-framework/devtools |
| MCP | wu-framework/mcp |
strict |
wu-framework/sandbox/iframe |
eval |
wu-framework/sandbox/html-parser + wu-framework/sandbox/iframe |
| Store sync | wu-framework/store-sync |
| Shadow | wu-framework/shadow |
| Windows | wu-framework/windows |
| Drag and drop | wu-framework/dnd |
| Ports / remote | wu-framework/ports |
.wuapp |
wu-framework/wuapp |
Si falta un import, WU_OPTIONAL_NOT_BUNDLED identifica el subsistema y la entrada que debes añadir. Añádelo una vez en el shell y recompila. Importar una entrada registra el subsistema; no concede permisos a las apps.
Tres fuentes de manifest
manifest: "fetch" es el valor predeterminado y carga wu.json. Un objeto manifest declara la misma información en el shell. Con manifest: "define", el módulo llama a wu.declare o pasa { manifest } como tercer argumento de wu.define; configura entry porque no existe un archivo previo que indique el módulo.
// shell.js
import { wu } from 'wu-framework/core';
await wu.init({ apps: [{
name: 'greeting', url: '/apps/greeting/',
manifest: 'define', entry: 'entry.js', grants: [],
}] });
await wu.mount('greeting', '#greeting-slot');
// apps/greeting/entry.js
import { wu } from 'wu-framework/core';
wu.define('greeting', {
mount(container) { container.textContent = 'Hello from WU'; },
unmount(container) { container.replaceChildren(); },
}, { manifest: { wu: { permissions: [] } } });
El HTML del shell debe contener #greeting-slot; el módulo de la app debe importar la misma instancia de WU que el shell. Los tres modos validan el manifest y aplican los grants del host. Declararlo desde JavaScript no convierte el código en un secreto ni crea una frontera de seguridad.
Identidad al cargar
definesAs permite registrar otra instancia de un módulo que conserva su nombre original. Durante esa carga, WU redirige define y declare al registro nuevo. Solo puede haber una carga activa por nombre redirigido: WU_DEFINE_REDIRECT_BUSY. Si el módulo define otro nombre por error, WU_DEFINE_NAME_MISMATCH informa los nombres observados y no repite un timeout que no resolvería el problema.
Montar dentro de otro Shadow DOM
mount(name, target) acepta un selector o un HTMLElement. Pasa el elemento cuando pertenece a un Shadow DOM: los selectores del documento no atraviesan esa frontera. La recuperación y el desmontaje conservan el mismo host; inspect() devuelve containerSelector: null para un montaje por elemento.
// The shell has already registered and initialized the editor app.
const shell = document.querySelector('my-shell');
const slot = shell.shadowRoot.querySelector('[data-editor-slot]');
await runtime.mount('editor', slot);
// Later, when the shell releases this view:
await runtime.unmount('editor', { force: true });
Instancias con recursos propios
Cada new WuCore() tiene su propio store, caché en memoria, métricas y enlaces de precarga. destroy() libera esos recursos y deja intactos los de otras instancias. Una caché inyectada con new WuCore({ cache }) pertenece al llamador y no se vacía automáticamente. Para persistencia, crea un WuCache con almacenamiento y namespace explícitos, y decide cuándo limpiarlo.
Registra los lifecycles con runtime.define(...) en la instancia correspondiente. Importar el singleton global wu registra en el host compartido. En una instancia independiente, espera runtime.timelineReady() antes de grabar cambios. Este patrón permite componer demos confiables en la misma página; no crea una frontera de seguridad para código arbitrario.
Consulta supervisión, recuperación y replay para superviseApp, createReplaySession y los métodos scoped reportError, now y random.
destroy() revoca puertos creados por el host, devuelve apps de ventanas separadas y libera recursos de drag and drop, shadow, health, replay y timeline de esa instancia. Las ofertas y destinos de arrastre también se liberan al revocar la lease de una app, incluido unmount o cuarentena.