# Ciclo de vida e propriedade

Registro, mount, props vivas, desmontagem, keep-alive e limpeza de recursos por aplicação.

Veja versões, mudanças e requisitos em [Framework 4.0 e CLI 1.2](/pt/docs/guides/releases/).


<span id="registro-no-equivale-a-montaje"></span>

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

## Registro não equivale a montagem

`wu.init` registra metadados e permissões. `wu.define` registra funções. `wu.mount` resolve uma app, prepara seu contêiner, carrega sua entrada se faltar a definição e executa o renderizador. O nome une essas três etapas.

```js
import { wu } from 'wu-framework';

let stop = () => {};
let abort = null;

wu.define('activity', {
  mount(container, { wu: appWu }) {
    abort = new AbortController();
    const output = document.createElement('output');
    const refresh = () => {
      output.textContent = String(appWu.store.get('activity.count') ?? 0);
    };
    container.replaceChildren(output);
    stop = appWu.store.on('activity.count', refresh);
    refresh();
    container.addEventListener('click', () => {
      appWu.emit('activity:opened', { source: 'counter' });
    }, { signal: abort.signal });
  },
  update(container, props) {
    container.setAttribute('aria-label', props.label ?? 'Actividad');
  },
  unmount(container) {
    stop();
    abort?.abort();
    container.replaceChildren();
  },
});
```

A app precisa de solicitações e concessões para ler `activity.count` e emitir `activity:opened`. O exemplo mantém a fachada recebida; o import de `wu` é usado para registrar o ciclo de vida.

<span id="slots-disponibles"></span>

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

## Slots disponíveis

| Slot | Assinatura / uso |
| --- | --- |
| `mount` | `(container, { appName, wu })`; obrigatório |
| `unmount` | `(container, context)`; libera renderizador, listeners e recursos próprios |
| `update` | `(container, nextProps)`; atualização sem desmontar |
| `hydrate` | `(container, { appName, wu, props })`; adota markup SSR |
| `deactivate` | `(container)`; invocado antes de ocultar com keep-alive |
| `activate` | `(container)`; reativa uma app preservada |

Os slots aceitam promises. Rejeitar uma promise em `mount` permite ao core limpar a tentativa e consultar a recuperação. Ocultar um erro sem renderizar nada pode fazer o WU considerar a montagem bem-sucedida; lance erros quando realmente não puder montar.

<span id="secuencia-observable"></span>

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

## Sequência observável

A montagem executa `beforeLoad`, o hook de plugin `beforeMount`, cria o sandbox, executa `afterLoad`, obtém ou carrega a definição, executa `beforeMount`, aguarda os estilos e chama `hydrate` ou `mount`. Depois, registra o estado montado e executa os hooks posteriores.

`afterLoad` é executado após criar o sandbox e antes de resolver/carregar o ciclo de vida. Use `afterMount` quando precisar reagir à árvore já montada.

O core serializa as transições no mesmo contêiner. Uma app não deve apagar um nó cuja propriedade já foi transferida a outra. Também há contagem de referências e desmontagem adiada para absorver ciclos de integração como React StrictMode. Se vários consumidores compartilham uma app, cada montagem deve ter uma desmontagem correspondente.

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

## Props vivas

```js
const updated = await wu.update('activity', { label: 'Actividad reciente' });
if (!updated) console.info('La app no aplicó esta actualización');
```

`update` não fabrica um renderizador se a app não implementar esse slot. Os adaptadores React e Vue mantêm props e atualizam sua raiz sem remontagem. As props iniciais são configuradas no registro do adaptador ou no SSR; `WuLifecycle.mount` não declara `context.props` para a montagem normal.

<span id="ocultar-y-destruir"></span>

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

## Ocultar e destruir

```js
await wu.hide('activity');
console.log(wu.isHidden('activity'));
await wu.show('activity');
await wu.unmount('activity', { force: true });
```

`hide` mantém DOM, iframe quando existe, estado, timers e listeners. A aplicação continua consumindo recursos; `deactivate` é o lugar para pausar trabalho próprio que não interessa enquanto ela está oculta. `show` restaura a visibilidade e executa `activate` sem carregar a entrada novamente.

`unmount` resolve `keepAlive` nesta ordem: `force` obriga a destruir; caso contrário, prevalece a opção da chamada, depois a configuração da app e, por fim, `false`. Desmontar completamente revoga a identidade com escopo, os listeners e os handlers associados. Uma referência a `context.wu` mantida após a desmontagem falha com `WU_APP_SCOPE_REVOKED`.

`wu.destroy()` limpa o runtime completo. Use quando o shell deixar de existir, não para mudar uma única seção. `wu.app(name, config)` entrega um wrapper com `mount`, `unmount`, `hide`, `show`, `remount`, `reload`, `verify`, `start`, `stop` e `destroy`.

<span id="wrapper-registro-diferido-y-concurrencia"></span>

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

## Wrapper: registro adiado e concorrência

`wu.app(name, config)` agrupa a identidade, a configuração e o destino de uma aplicação. Criar o wrapper mantém esses dados; o registro efetivo ocorre na montagem, pelo core e sua validação de manifesto e permissões. Se o core ainda não tiver sido iniciado, o wrapper inicia essa configuração antes de montar.

```js
const widget = wu.app('widget', {
  url: '/apps/widget',
  container: '#widget-slot',
  framework: 'vue',
  grants: [],
});
await widget.mount();
console.log(widget.isMounted, widget.info.container);
await widget.hide();
await widget.show();
await widget.unmount({ force: true });
```

A URL deve servir o manifesto de `widget`. `mount(selector)` permite escolher outro destino e o mantém para chamadas posteriores sem argumento. Os métodos de montagem, desmontagem, visibilidade, remount e reload resolvem para o mesmo wrapper, permitindo inspecionar seu estado ao terminar.

| Membro | Uso |
| --- | --- |
| `mount(selector?)` / `start(selector?)` | Registrar se necessário e montar em um seletor string |
| `unmount(options?)` / `stop()` | Desmontar; stop usa as opções padrão |
| `hide()` / `show()` | Manter e reativar uma app montada |
| `remount(selector?)` | Forçar a desmontagem e montar novamente |
| `reload()` | Desmontar, limpar os caches disponíveis de loader/manifesto e montar novamente |
| `isMounted` / `isHidden` | Consultar o estado do wrapper e do core |
| `info` | Nome, URL, seletor, montagem e status |
| `verify()` | Inspecionar registro, seletor e Shadow DOM do contêiner |

Se outro `init` estiver em andamento, o wrapper o aguarda e registra sua app depois, se ela ainda faltar. Dois mounts concorrentes no **mesmo wrapper** compartilham uma promise de registro; cada montagem continua participando da propriedade e da contagem de referências do core. Uma falha libera essa promise para permitir uma nova tentativa. Um registro existente do host é mantido, sem sobrescrever suas concessões com as de outro wrapper.

`reload()` não invalida o cache nativo de módulos ESM do navegador nem garante baixar uma versão diferente da mesma URL. Para atualizar uma versão implantada, publique entradas com identidade de build e coordene seu carregamento pelo shell.

`verify().container.hasContent` inspeciona os filhos do ShadowRoot do slot; um resultado false não comprova que um renderizador com propriedade própria ou light DOM esteja vazio. `WuApp.destroy()` remove a app do mapa público, mas não limpa todos os registros de manifesto associados. Para remover um renderizador, use `unmount`; para reinicializar o shell completo, use `wu.destroy()` e um novo `init`, em vez de tratar o destroy do wrapper como uma operação geral de substituição de identidade.

<span id="referencia-de-implementación"></span>

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

## Referência de implementação

Slots: `src/index.d.ts`; definição: `src/core/wu-core.js`; montagem: `src/core/wu-core.js`; atualização: `src/core/wu-core.js`; encerramento: `src/core/wu-core.js`; keep-alive: `src/core/wu-core.js`; wrapper: `src/core/wu-app.js`. Testes: `tests/unit/keep-alive.test.js`, `tests/unit/props-channel.test.js`, `tests/unit/shared-container-navigation.test.js`, `tests/unit/scoped-events-teardown.test.js`.