# Referência de hooks, plugins e timeline

Estenda o ciclo de vida, instale plugins com concessões e controle projeções de tempo sem confundir suas autoridades.

Um hook modifica o percurso do ciclo de vida; um plugin agrupa setup, permissões e limpeza; a timeline mantém um diário de projeções. Cada mecanismo tem um proprietário e uma forma de encerrar sua atividade.

<span id="interceptar-una-fase"></span>

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

## Interceptar uma fase

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

const removeGuard = wu.hooks.use('beforeMount', createGuardHook(context => {
  return context.appName !== 'disabled-app';
}), { name: 'availability' });
// Al retirar esta extensión:
removeGuard();
```

As fases disponíveis são before/after Init, Load, Mount, Update, Unmount e Destroy. Uma prioridade maior é executada antes. Omitir `next()` cancela a cadeia; `failOpen: true` permite continuar após uma falha do middleware. Um guard de UI não substitui o controle de papéis nem as concessões do core.

<span id="conceder-autoridad-a-un-plugin"></span>

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

## Conceder autoridade a um plugin

As permissões de plugin são `mount`, `events`, `store`, `apps`, `config` e `unsafe`. Um plugin solicita esses nomes e o host concede `options.grants` na instalação. Não reutilize os nomes `store.read` ou `rpc.call` como concessões de plugin: eles pertencem ao contrato de aplicações.

Aguarde `pluginSystem.use` ou `pluginSystem.ready` antes de depender do setup. A instalação por uma factory assíncrona também participa dessa inicialização. O plugin executa código do host; sua API reduzida não elimina privilégios capturados em closures.

<span id="grabar-antes-de-escribir"></span>

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

## Gravar antes de escrever

```js
await wu.timelineReady();
wu.timeline.record({ maxEntries: 500 });
wu.store.set('demo.count', 1);
wu.store.set('demo.count', 2);
await wu.timeline.seek(0, { apps: false, props: false });
await wu.timeline.live();
wu.timeline.stop();
```

A fachada `wu.timeline` mantém métodos encadeáveis para controles síncronos. O objeto real retornado por `timelineReady` tem retornos diferentes; use a fachada nos exemplos desta referência. Seek rematerializa store, props e composição conforme suas opções; não rebobina rede, timers ou infraestrutura.

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

## wu.hooks.use

Instala middleware de ciclo de vida com prioridade e limpeza individual.

`wu.hooks.use(phase, middleware, options?): () => void`

- **Parâmetros:** Fase válida, middleware(context,next); options: name, priority, failOpen.
- **Retorno:** Função de remoção; a declaração TypeScript indica void.
- **Erros:** Fase desconhecida ou callback inválido lança erro; omitir next cancela a cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** stop() remove apenas esse middleware.

```js
const stop = wu.hooks.use('beforeMount', async (context, next) => {
  console.log(context.appName);
  await next();
}, { name: 'mount-log', priority: 10 });
```

Referência: `src/core/wu-hooks.js`.

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

## wu.hooks.useMultiple

Instala o mesmo middleware em várias fases.

`wu.hooks.useMultiple(phases, middleware, options?): () => void`

- **Parâmetros:** Array de fases; use um name estável para identificar cada registro derivado.
- **Retorno:** Limpeza conjunta.
- **Erros:** Cada fase deve existir; o registro não é atômico se uma fase posterior falhar.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** stop() remove as instalações criadas.

```js
const stop = wu.hooks.useMultiple(['beforeMount', 'beforeUnmount'], async (ctx, next) => {
  await next();
}, { name: 'trace' });
```

Referência: `src/core/wu-hooks.js`.

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

## wu.hooks.remove

Remove o middleware identificado pela fase e pelo nome.

`wu.hooks.remove(phase, name): void`

- **Parâmetros:** phase e o name do registro.
- **Retorno:** void; a ausência não lança erro.
- **Erros:** Nomes duplicados tornam a remoção ambígua; prefira a limpeza individual.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala novos recursos.

```js
wu.hooks.remove('beforeMount', 'mount-log');
```

Referência: `src/core/wu-hooks.js`.

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

## wu.hooks.getHooks

Consulta os metadados do middleware instalado.

`wu.hooks.getHooks(phase?): object | object[]`

- **Parâmetros:** Fase opcional.
- **Retorno:** Sem fase: mapa de metadados; com fase: array de registros.
- **Erros:** Com fase, retorna registros internos; não os modifique como API de configuração.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala novos recursos.

```js
console.log(wu.hooks.getHooks());
```

Referência: `src/core/wu-hooks.js`.

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

## wu.hooks.getStats

Consulta a distribuição de hooks e os registros de execução.

`wu.hooks.getStats(): object`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Objeto de métricas.
- **Erros:** O log de execução tem capacidade limitada.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala novos recursos.

```js
console.log(wu.hooks.getStats());
```

Referência: `src/core/wu-hooks.js`.

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

## wu.hooks.cleanup

Remove middleware de uma fase ou de todas.

`wu.hooks.cleanup(phase?): void`

- **Parâmetros:** Fase opcional; sem ela, também esvazia o log de execução.
- **Retorno:** void.
- **Erros:** Não cancela por si só um callback que já está sendo executado.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Libera registros; recursos criados pelos callbacks precisam de sua própria limpeza.

```js
wu.hooks.cleanup('beforeMount');
```

Referência: `src/core/wu-hooks.js`.

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

## createSimpleHook

Converte um callback em middleware que continua a cadeia.

`createSimpleHook(fn): Function`

- **Parâmetros:** fn(context) pode ser assíncrono.
- **Retorno:** Middleware async(context,next).
- **Erros:** Os erros do callback seguem a política da factory e da cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Instale com hooks.use e mantenha a limpeza desse registro.

```js
import { createSimpleHook } from 'wu-framework';
const middleware = createSimpleHook(ctx => console.log(ctx.appName));
```

Aguarda o callback e depois invoca next.

Referência: `src/core/wu-hooks.js`.

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

## createConditionalHook

Executa um callback se a condição for verdadeira e continua.

`createConditionalHook(condition, fn): Function`

- **Parâmetros:** condition(context) e fn(context).
- **Retorno:** Middleware async(context,next).
- **Erros:** Os erros do callback seguem a política da factory e da cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Instale com hooks.use e mantenha a limpeza desse registro.

```js
import { createConditionalHook } from 'wu-framework';
const middleware = createConditionalHook(ctx => ctx.appName === 'catalog', ctx => console.log(ctx));
```

A condição não é um guard de cancelamento: uma condição falsa continua a cadeia.

Referência: `src/core/wu-hooks.js`.

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

## createGuardHook

Continua a cadeia apenas quando o guard permite.

`createGuardHook(shouldContinue): Function`

- **Parâmetros:** shouldContinue(context), síncrono ou promise.
- **Retorno:** Middleware async(context,next).
- **Erros:** Os erros do callback seguem a política da factory e da cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Instale com hooks.use e mantenha a limpeza desse registro.

```js
import { createGuardHook } from 'wu-framework';
const middleware = createGuardHook(ctx => ctx.appName !== 'disabled-app');
```

Se retornar false, não chama next; não substitui concessões nem autorização do servidor.

Referência: `src/core/wu-hooks.js`.

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

## createTransformHook

Transforma o contexto que o próximo middleware receberá.

`createTransformHook(transformer): Function`

- **Parâmetros:** transformer(context) retorna dados para o contexto.
- **Retorno:** Middleware async(context,next).
- **Erros:** Os erros do callback seguem a política da factory e da cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Instale com hooks.use e mantenha a limpeza desse registro.

```js
import { createTransformHook } from 'wu-framework';
const middleware = createTransformHook(ctx => ({ ...ctx, traceLabel: 'catalog' }));
```

Não equivale a configurar o core fora dos campos consumidos por esse ciclo de vida.

Referência: `src/core/wu-hooks.js`.

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

## createTimedHook

Limita quanto tempo o middleware espera por um callback.

`createTimedHook(fn, timeout?: number): Function`

- **Parâmetros:** fn(context); timeout padrão de 5000 ms.
- **Retorno:** Middleware async(context,next).
- **Erros:** Os erros do callback seguem a política da factory e da cadeia.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Instale com hooks.use e mantenha a limpeza desse registro.

```js
import { createTimedHook } from 'wu-framework';
const middleware = createTimedHook(async ctx => console.log(ctx.appName), 1000);
```

Uma falha ou um timeout é registrado e a cadeia continua; o trabalho original não é abortado automaticamente.

Referência: `src/core/wu-hooks.js`.

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

## createPlugin

Constrói um plugin com nome, permissões solicitadas e callbacks.

`createPlugin(config): WuPlugin`

- **Parâmetros:** config com name; install/uninstall e hooks são opcionais.
- **Retorno:** Objeto de plugin; criar não instala.
- **Erros:** Nome/config inválidos podem lançar erro.
- **Permissões:** O plugin solicita permissões; o host as concede ao chamar use.
- **Limpeza:** Instale com pluginSystem.use e remova com uninstall.

```js
import { createPlugin } from 'wu-framework';
const plugin = createPlugin({ name: 'catalog-observer', permissions: ['events'], install(api) { console.log(api.version); } });
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.use

Instala um plugin e aguarda seu setup antes de considerá-lo disponível.

`wu.pluginSystem.use(pluginOrFactory, options?): Promise<boolean>`

- **Parâmetros:** Plugin ou factory async; options.grants e compatibility configuram a autoridade.
- **Retorno:** true se for instalado; rejeita falhas de validação/setup.
- **Erros:** Permissões obrigatórias sem concessões, duplicados e erros de install podem causar rejeição.
- **Permissões:** Permissões de plugin: mount, events, store, apps, config, unsafe; diferentes das capacidades de app.
- **Limpeza:** await uninstall(name) revoga sua API e executa a limpeza.

```js
await wu.pluginSystem.use({
  name: 'catalog-observer', permissions: ['events'],
  install(api) { console.log(api.version); },
}, { grants: ['events'] });
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.ready

Aguarda instalações pendentes e expõe suas falhas ao bootstrap.

`wu.pluginSystem.ready(): Promise<boolean>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** true ao terminar corretamente.
- **Erros:** Rejeita o primeiro erro pendente e inclui pendingPluginErrors.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não desinstala plugins instalados com sucesso.

```js
await wu.pluginSystem.ready();
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.uninstall

Remove um plugin e sua autoridade associada.

`wu.pluginSystem.uninstall(name): Promise<boolean>`

- **Parâmetros:** Nome exato do plugin.
- **Retorno:** Booleano de desinstalação.
- **Erros:** Uninstall pode falhar; consulte o erro e os diagnósticos.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Invoca o hook uninstall e libera hooks/listeners pertencentes ao plugin.

```js
await wu.pluginSystem.uninstall('catalog-observer');
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.getPlugin

Consulta a definição de um plugin instalado.

`wu.pluginSystem.getPlugin(name): WuPlugin | undefined`

- **Parâmetros:** Nome exato.
- **Retorno:** Plugin ou undefined.
- **Erros:** Não existe até a instalação ser concluída.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala novos recursos.

```js
console.log(wu.pluginSystem.getPlugin('catalog-observer')?.name);
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.getStats

Lista plugins, permissões concedidas e hooks ativos.

`wu.pluginSystem.getStats(): object`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Objeto com totalPlugins, plugins e hooks.
- **Erros:** Não verifica efeitos externos do plugin.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala novos recursos.

```js
console.log(wu.pluginSystem.getStats());
```

Referência: `src/core/wu-plugin.js`.

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

## wu.pluginSystem.cleanup

Desinstala todos os plugins do sistema.

`wu.pluginSystem.cleanup(): Promise<void>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Promise ao terminar o percurso de desinstalação.
- **Erros:** As falhas seguem o contrato de uninstall.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Afeta todos os plugins; pertence ao encerramento do host.

```js
await wu.pluginSystem.cleanup();
```

Referência: `src/core/wu-plugin.js`.

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

## wu.timelineReady

Carrega o gravador antes das primeiras escritas que você deseja capturar.

`wu.timelineReady(): Promise<unknown>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Instância real do gravador; não é a fachada encadeável.
- **Erros:** Rejeita erros de download/import do chunk.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** wu.timeline.stop() remove observadores; clear reinicia o diário.

```js
await wu.timelineReady();
wu.timeline.record();
```

Referência: `src/index.js`.

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

## wu.timeline.record

Inicia o diário a partir do estado e das apps atuais.

`wu.timeline.record(options?: { snapshotEvery?: number; maxEntries?: number }): WuTimelineFacade`

- **Parâmetros:** Frequência de snapshots e limite de entradas opcionais.
- **Retorno:** WuTimelineFacade
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** stop() remove os taps.

```js
await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 25, maxEntries: 500 });
```

A fachada retorna a si mesma; o gravador real retorna status. Sem timelineReady, o carregamento adiado pode perder escritas iniciais.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.stop

Interrompe a captura mantendo o diário para inspeção.

`wu.timeline.stop(): WuTimelineFacade`

- **Parâmetros:** Sem argumentos.
- **Retorno:** WuTimelineFacade
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Remove taps do store e do barramento.

```js
wu.timeline.stop();
```

Não interrompe timers, solicitações ou processos criados pelas aplicações.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.clear

Esvazia o diário e adota a situação atual como nova base.

`wu.timeline.clear(): WuTimelineFacade`

- **Parâmetros:** Sem argumentos.
- **Retorno:** WuTimelineFacade
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não substitui stop se você deseja parar de gravar.

```js
wu.timeline.clear();
```

Não apaga o estado de negócio nem reverte efeitos externos.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.seek

Materializa uma posição do diário em suas projeções.

`wu.timeline.seek(position: number, options?: { store?: boolean; apps?: boolean; props?: boolean }): Promise<WuTimelineStatus>`

- **Parâmetros:** Índice 0..length; seleciona store/apps/props.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Volte a live para recuperar a posição final.

```js
const status = await wu.timeline.seek(0, { store: true, apps: false, props: false });
```

Não reverte HTTP, timers ou infraestrutura. As escritas feitas no passado não criam uma nova ramificação.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.live

Materializa o final do diário.

`wu.timeline.live(): Promise<WuTimelineStatus>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Mantém o gravador até stop.

```js
await wu.timeline.live();
```

Voltar a live descarta alterações não registradas durante a posição histórica.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.stepBack

Recua uma posição no diário.

`wu.timeline.stepBack(): Promise<WuTimelineStatus>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** stop libera a captura quando a sessão terminar.

```js
await wu.timeline.stepBack();
```

Limita-se às projeções reproduzíveis do gravador.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.stepForward

Avança uma posição no diário.

`wu.timeline.stepForward(): Promise<WuTimelineStatus>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** stop libera a captura quando a sessão terminar.

```js
await wu.timeline.stepForward();
```

Não reproduz efeitos externos de uma ação.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.export

Serializa entradas, snapshots e a base das apps.

`wu.timeline.export(): Promise<WuTimelineExport>`

- **Parâmetros:** Sem argumentos.
- **Retorno:** Promise<WuTimelineExport>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** O host decide onde salvar/exportar o objeto.

```js
const journal = await wu.timeline.export();
```

Pode conter estado da aplicação; não é uma auditoria durável automática.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.import

Carrega um diário serializado para inspeção.

`wu.timeline.import(journal: WuTimelineExport): Promise<WuTimelineStatus>`

- **Parâmetros:** Objeto de exportação compatível.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Afeta o gravador; escolha explicitamente a projeção posterior.

```js
await wu.timeline.import(journal);
```

Valide a procedência do estado; importar não executa um sandbox remoto.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.ingest

Combina entradas com a ordem do diário e uma base comum vazia.

`wu.timeline.ingest(entries: WuTimelineEntry[]): Promise<WuTimelineStatus>`

- **Parâmetros:** Entradas com relógio Lamport e identidade do site.
- **Retorno:** Promise<WuTimelineStatus>
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não abre nem autentica um transporte.

```js
await wu.timeline.ingest(remoteEntries);
```

A mesclagem não materializa todo o estado na UI por si só; requer uma base compartilhada e regras de projeção.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.entries

Lê as entradas mantidas pelo gravador.

`wu.timeline.entries(): WuTimelineEntry[]`

- **Parâmetros:** Sem argumentos.
- **Retorno:** WuTimelineEntry[]
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala recursos.

```js
console.table(wu.timeline.entries());
```

O array é copiado superficialmente; não o use para modificar o gravador.

Referência: `src/core/wu-timeline.js`.

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

## wu.timeline.status

Consulta captura, posição, relógios e capacidade ocupada.

`wu.timeline.status(): WuTimelineStatus`

- **Parâmetros:** Sem argumentos.
- **Retorno:** WuTimelineStatus
- **Erros:** A família assíncrona pode rejeitar erros de chunk, formato ou materialização.
- **Permissões:** Host; a fachada com escopo não expõe administração global.
- **Limpeza:** Não instala recursos.

```js
console.log(wu.timeline.status());
```

loaded indica se o chunk já está disponível; não garante que esteja gravando.

Referência: `src/core/wu-timeline.js`.