WU / DOCSMICROFRONTENDS UNIVERSAIS
PT

Hooks, plugins, timeline e IA

Extensões e subsistemas adiados do runtime com limites precisos de execução, registro e autoridade.

Middleware de lifecycle

Os hooks recebem (context, next). Chamar next() permite continuar; omiti-lo cancela a cadeia. Uma prioridade maior é executada antes. O registro retorna uma função de cancelamento da inscrição que você deve guardar se o middleware tiver um lifecycle mais curto que o shell. A declaração TypeScript de use indica void; o runtime fornece esse cleanup.

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

// Después de observar el escenario:
remove();

As fases são beforeInit, afterInit, beforeLoad, afterLoad, beforeMount, afterMount, beforeUpdate, afterUpdate, beforeUnmount, afterUnmount, beforeDestroy e afterDestroy. O contexto depende da fase; nem todos os hooks recebem lifecycle, sandbox ou props.

Um middleware que lança um erro antes de next cancela por padrão; failOpen: true permite continuar diante dessa falha. Os helpers exportados createSimpleHook, createConditionalHook, createGuardHook, createTransformHook e createTimedHook constroem middleware. O helper timed registra seu erro e chama next: não é adequado como controle que deva fechar o acesso diante de um timeout.

Plugin com grants explícitos

let stop = () => {};

await wu.pluginSystem.use({
  name: 'catalog-observer',
  permissions: ['events'],
  install(api) {
    stop = api.on('catalog:selected', (event) => {
      console.info('Selección observada', event.data);
    });
  },
  uninstall() { stop(); },
}, { grants: ['events'] });

// Al retirarlo:
await wu.pluginSystem.uninstall('catalog-observer');

use aceita um objeto ou uma factory, aguarda a instalação e valida as permissões. ready() permite aguardar instalações pendentes; init já espera essa barreira. O timeout padrão dos hooks de plugins é 5000 ms.

As factories recebem opções, não o core. Os grants do host são copiados antes de chamar a factory para que ela não amplie suas opções e se autorize sozinha. Ainda assim, um plugin é código executado no host: a API filtrada não isola closures nem o acesso global que esse código já tem.

Timeline e tempo de carregamento

await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 64, maxEntries: 5000 });

wu.store.set('demo.counter', 1);
wu.store.set('demo.counter', 2);

await wu.timeline.stepBack();
console.log(wu.store.get('demo.counter'));
await wu.timeline.live();

const recording = await wu.timeline.export();
wu.timeline.stop();

timelineReady() carrega o chunk antes de começar. Se você chamar record() pela primeira vez e gravar imediatamente, a gravação pode ocorrer antes de o registro adiado estar preparado. A facade mantém a intenção de record/stop enquanto o módulo chega; para capturar a próxima gravação sem ambiguidade, use ready primeiro.

O journal registra gravações no store, eventos e lifecycle/props que passam pelo WU. Tem um limite padrão de 5000 entradas e snapshots a cada 64. seek, stepBack, stepForward, live, export, import, entries e status permitem inspecionar esse registro.

Retroceder rematerializa projeções; não reverte timers internos das apps, solicitações HTTP nem infraestrutura. Quando você está no passado, novas gravações não são adicionadas ao journal, e voltar a live as descarta. Não existe branching do histórico nem auditoria durável implícita.

IA opcional

O import principal instala um proxy lazy. Métodos encadeáveis como provider, action, trigger, capability e workflow podem enfileirar configurações enquanto o chunk chega; operações de valor exigem aguardar o módulo real. aiReady() é a forma explícita de obtê-lo.

const ai = await wu.aiReady();
ai.init({ permissions: { executeActions: true } });

ai.action('sum_local', {
  description: 'Suma dos valores de demostración sin efectos externos',
  parameters: {
    type: 'object',
    properties: {
      a: { type: 'number' },
      b: { type: 'number' },
    },
    required: ['a', 'b'],
  },
  handler: async ({ a, b }) => ({ total: a + b }),
});

const result = await ai.execute('sum_local', { a: 2, b: 3 });
console.log(result);

Registrar e executar essa action local não exige enviar dados a um modelo. Para conversação, existem providers, send, stream, json, agent, triggers e workflows, com suas próprias permissões e configurações. Não use uma chave privada de serviço em um bundle público.

Actions validam parâmetros, verificam executeActions, consultam permissões adicionais/condicionais e podem pedir confirmação. dangerous: true exige confirmação no código atual. Os resultados de execução usam um envelope { success, result? , reason? }: uma rejeição de permissões pode ser um resultado negativo, não uma exceção.

Os padrões permitem readStore e emitEvents; writeStore, readDOM, modifyDOM, readDiagnostics, navigate, executeActions, network e allowDirectKey começam desativados. São flags do módulo IA, independentes dos grants da app e da autorização do servidor.

MCP e automação

wu.mcp.connect(url, options), disconnect() e isConnected() expõem a ponte cliente adiada. O pacote também inclui o binário wu-mcp-server e seu subpath. A ponte pode inspecionar e alterar o estado e a interface conforme os controles do módulo; não acrescenta, por si só, dry-run vinculante, idempotência, autorização de domínio, rollback ou um registro permanente.

Para um agente que opera recursos reais, use um serviço que receba comandos validados e retorne receipts. O store pode projetar seu progresso; a action não deve se tornar uma closure que exerce privilégios sem revalidação.

Referência de implementação

Hooks: src/core/wu-hooks.js; plugins: src/core/wu-plugin.js; facade da timeline: src/index.js; journal: src/core/wu-timeline.js; IA: src/ai/wu-ai.js, src/ai/wu-ai-actions.js, src/ai/wu-ai-actions.js; padrões: src/ai/wu-ai-permissions.js; MCP: src/index.js. Testes: tests/unit/plugin-security.test.js, tests/unit/timeline-facade.test.js, tests/unit/lazy-ai-proxy.test.js, tests/unit/ai-actions.test.js, tests/unit/mcp-bridge-security.test.js.

CONSTRUA O WU CONOSCO

Encontrou um bug? Tem uma ideia?

Sua experiência melhora o WU. Conte o que falhou ou ajude a manter seu desenvolvimento.