# Comparar una versión en sombra

Ejecuta una gemela oculta, compara sus salidas WU y entiende los límites de la comparación.

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.

La app primaria permanece visible y montada. `wu.shadow` monta una gemela oculta e inerte, replica entradas que cruzan WU y registra sus salidas de la facade. Es útil para comparar una reescritura o una actualización antes de reemplazar la app visible.

```js
import { wu } from 'wu-framework/core';
import 'wu-framework/shadow';

// cart must already be registered and mounted.
await wu.shadow.start('cart', { url: '/apps/cart-v2/', rpcTimeout: 5000 });
try {
  await wu.update('cart', { currency: 'EUR' });
  const report = wu.shadow.report('cart');
  console.log(report.equal, report.dom, report.outputs);
} finally {
  await wu.shadow.stop('cart');
}
```

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

## Entradas y salidas

La gemela recibe props, eventos y lecturas del store. Sus escrituras usan una capa propia. Sus peticiones RPC o contratos reciben respuestas registradas de la primaria para el mismo canal y argumentos. `emit`, `handle` y `provide` de la gemela se registran sin publicar sus efectos a través de WU.

La comparación cubre operaciones de la facade, no intercepta cualquier efecto del navegador. Una petición `fetch` directa o una escritura externa hecha por el código de la gemela sigue siendo responsabilidad de esa app. Tampoco reproduce clics del usuario ni demuestra equivalencia visual de layout.

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

## Leer el informe

`report().dom` compara árboles normalizados sin atributos internos; `outputs` compara operaciones registradas y sus argumentos. `equal` significa que esas comparaciones no encontraron diferencias. `unmatchedCalls` identifica peticiones sin pareja; después de `rpcTimeout` rechazan con `WU_SHADOW_NO_TWIN_CALL`. No es una aprobación automática del despliegue.

`start` devuelve el primer informe; `report` devuelve el actual o `null`; `stop` libera gemela, hooks y esperas y devuelve el último informe. `sessions` enumera sesiones. La primaria debe estar montada; una segunda sombra falla con `WU_SHADOW_EXISTS`. La gemela conserva los grants de la primaria y se registra como `<app>~shadow` salvo que configures `name`.

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

## Interceptar operaciones del host

```js
const release = wu.intercept('cart', (kind, args, next) => {
  if (kind === 'store.set') console.log('cart writes', args[0]);
  return next(...args);
});
// Remove the middleware when the host no longer needs it.
release();
```

`intercept` devuelve una función de limpieza. `next(...args)` continúa la operación; devolver otro resultado la sustituye. Varios interceptores se ejecutan en orden de registro. Debes conservar el contrato síncrono o asíncrono esperado por la app.

El reporte de shadow incluye `props.failures` cuando una actualización de props no llega al twin. Mientras existan esas fallas, `equal` es `false`; no interpretes una comparación parcial como equivalencia del despliegue.