# 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](/es/docs/guides/releases/) antes de actualizar un proyecto existente.

<span class="section-anchor" id="section-1"></span>

## 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.

```js
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.

<span class="section-anchor" id="section-2"></span>

## 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.

```js
// 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');
```

```js
// 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.

<span class="section-anchor" id="section-3"></span>

## 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.

<span class="section-anchor" id="section-4"></span>

## 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.

```js
// 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 });
```

<span class="section-anchor" id="section-5"></span>

## 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](/es/docs/framework/runtime-reliability/) 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.