Referencia de hooks, plugins y timeline
Extiende el lifecycle, instala plugins con grants y controla proyecciones de tiempo sin confundir sus autoridades.
Un hook modifica el recorrido de lifecycle; un plugin agrupa setup, permisos y cleanup; timeline conserva un journal de proyecciones. Cada mecanismo tiene un dueño y una forma de terminar su actividad.
Interceptar una fase
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();
Las fases disponibles son before/after Init, Load, Mount, Update, Unmount y Destroy. Una prioridad mayor se ejecuta antes. Omitir next() cancela la cadena; failOpen: true permite continuar tras un fallo del middleware. Un guard de UI no sustituye el control de roles ni los grants del core.
Conceder autoridad a un plugin
Los permisos de plugin son mount, events, store, apps, config y unsafe. Un plugin solicita esos nombres y el host concede options.grants al instalar. No reutilices como grants de plugin los nombres store.read o rpc.call: pertenecen al contrato de aplicaciones.
Espera pluginSystem.use o pluginSystem.ready antes de depender del setup. Instalar desde una factory asíncrona también participa en ese arranque. El plugin ejecuta código host; su API reducida no elimina privilegios capturados en closures.
Grabar antes de escribir
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();
La facade wu.timeline conserva métodos chainable para controles síncronos. El objeto real devuelto por timelineReady tiene retornos distintos; utiliza la facade en los ejemplos de esta referencia. Seek rematerializa store, props y composición según sus opciones; no rebobina red, timers ni infraestructura.
wu.hooks.use
Instala middleware de lifecycle con prioridad y limpieza individual.
wu.hooks.use(phase, middleware, options?): () => void
- Parámetros: Fase válida, middleware(context,next); options: name, priority, failOpen.
- Retorno: Función de baja; la declaración TypeScript indica void.
- Errores: Fase desconocida o callback inválido lanza; omitir next cancela la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: stop() retira solo ese middleware.
const stop = wu.hooks.use('beforeMount', async (context, next) => {
console.log(context.appName);
await next();
}, { name: 'mount-log', priority: 10 });
Referencia: src/core/wu-hooks.js.
wu.hooks.useMultiple
Instala un mismo middleware en varias fases.
wu.hooks.useMultiple(phases, middleware, options?): () => void
- Parámetros: Array de fases; usa un name estable para identificar cada registro derivado.
- Retorno: Cleanup conjunto.
- Errores: Cada fase debe existir; no es un registro atómico si una fase posterior falla.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: stop() retira las instalaciones creadas.
const stop = wu.hooks.useMultiple(['beforeMount', 'beforeUnmount'], async (ctx, next) => {
await next();
}, { name: 'trace' });
Referencia: src/core/wu-hooks.js.
wu.hooks.remove
Retira el middleware identificado por fase y nombre.
wu.hooks.remove(phase, name): void
- Parámetros: phase y el name de registro.
- Retorno: void; ausencia no lanza.
- Errores: Nombres duplicados vuelven ambigua la baja; prefiere el cleanup individual.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos nuevos.
wu.hooks.remove('beforeMount', 'mount-log');
Referencia: src/core/wu-hooks.js.
wu.hooks.getHooks
Consulta metadatos de middleware instalado.
wu.hooks.getHooks(phase?): object | object[]
- Parámetros: Fase opcional.
- Retorno: Sin fase: mapa de metadatos; con fase: array de registros.
- Errores: Con fase devuelve registros internos; no los mutas como API de configuración.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos nuevos.
console.log(wu.hooks.getHooks());
Referencia: src/core/wu-hooks.js.
wu.hooks.getStats
Consulta distribución de hooks y registros de ejecución.
wu.hooks.getStats(): object
- Parámetros: Sin argumentos.
- Retorno: Objeto de métricas.
- Errores: El log de ejecución tiene capacidad limitada.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos nuevos.
console.log(wu.hooks.getStats());
Referencia: src/core/wu-hooks.js.
wu.hooks.cleanup
Retira middleware de una fase o de todas.
wu.hooks.cleanup(phase?): void
- Parámetros: Fase opcional; sin ella también vacía el log de ejecución.
- Retorno: void.
- Errores: No cancela por sí solo un callback que ya está ejecutándose.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Libera registros; recursos creados por callbacks necesitan su propio cleanup.
wu.hooks.cleanup('beforeMount');
Referencia: src/core/wu-hooks.js.
createSimpleHook
Convierte un callback en middleware que continúa la cadena.
createSimpleHook(fn): Function
- Parámetros: fn(context) puede ser asíncrono.
- Retorno: Middleware async(context,next).
- Errores: Los errores del callback siguen la política de la factory y la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Instálalo con hooks.use y conserva el cleanup de ese registro.
import { createSimpleHook } from 'wu-framework';
const middleware = createSimpleHook(ctx => console.log(ctx.appName));
Espera el callback y después invoca next.
Referencia: src/core/wu-hooks.js.
createConditionalHook
Ejecuta un callback si la condición resulta verdadera y continúa.
createConditionalHook(condition, fn): Function
- Parámetros: condition(context) y fn(context).
- Retorno: Middleware async(context,next).
- Errores: Los errores del callback siguen la política de la factory y la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Instálalo con hooks.use y conserva el cleanup de ese registro.
import { createConditionalHook } from 'wu-framework';
const middleware = createConditionalHook(ctx => ctx.appName === 'catalog', ctx => console.log(ctx));
La condición no es un guard de cancelación: una condición falsa continúa la cadena.
Referencia: src/core/wu-hooks.js.
createGuardHook
Continúa la cadena solamente cuando el guard lo permite.
createGuardHook(shouldContinue): Function
- Parámetros: shouldContinue(context), síncrono o promesa.
- Retorno: Middleware async(context,next).
- Errores: Los errores del callback siguen la política de la factory y la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Instálalo con hooks.use y conserva el cleanup de ese registro.
import { createGuardHook } from 'wu-framework';
const middleware = createGuardHook(ctx => ctx.appName !== 'disabled-app');
Si devuelve false no llama a next; no sustituye grants ni autorización de servidor.
Referencia: src/core/wu-hooks.js.
createTransformHook
Transforma el contexto que recibirá el siguiente middleware.
createTransformHook(transformer): Function
- Parámetros: transformer(context) devuelve datos para el contexto.
- Retorno: Middleware async(context,next).
- Errores: Los errores del callback siguen la política de la factory y la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Instálalo con hooks.use y conserva el cleanup de ese registro.
import { createTransformHook } from 'wu-framework';
const middleware = createTransformHook(ctx => ({ ...ctx, traceLabel: 'catalog' }));
No equivale a configurar el core fuera de los campos consumidos por ese lifecycle.
Referencia: src/core/wu-hooks.js.
createTimedHook
Limita cuánto espera el middleware a un callback.
createTimedHook(fn, timeout?: number): Function
- Parámetros: fn(context); timeout por defecto 5000 ms.
- Retorno: Middleware async(context,next).
- Errores: Los errores del callback siguen la política de la factory y la cadena.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Instálalo con hooks.use y conserva el cleanup de ese registro.
import { createTimedHook } from 'wu-framework';
const middleware = createTimedHook(async ctx => console.log(ctx.appName), 1000);
Un fallo o timeout se registra y la cadena continúa; el trabajo original no se aborta automáticamente.
Referencia: src/core/wu-hooks.js.
createPlugin
Construye un plugin con nombre, permisos solicitados y callbacks.
createPlugin(config): WuPlugin
- Parámetros: config con name; install/uninstall y hooks son opcionales.
- Retorno: Objeto de plugin; crear no instala.
- Errores: Nombre/config inválidos pueden lanzar.
- Permisos: El plugin solicita permisos; el host los concede al llamar use.
- Limpieza: Instala con pluginSystem.use y retira con uninstall.
import { createPlugin } from 'wu-framework';
const plugin = createPlugin({ name: 'catalog-observer', permissions: ['events'], install(api) { console.log(api.version); } });
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.use
Instala un plugin y espera su setup antes de considerarlo disponible.
wu.pluginSystem.use(pluginOrFactory, options?): Promise<boolean>
- Parámetros: Plugin o factory async; options.grants y compatibility configuran autoridad.
- Retorno: true si queda instalado; rechaza fallos de validación/setup.
- Errores: Permisos requeridos sin grants, duplicados y errores de install pueden rechazar.
- Permisos: Permisos plugin: mount, events, store, apps, config, unsafe; distintos de capabilities de app.
- Limpieza: await uninstall(name) revoca su API y ejecuta cleanup.
await wu.pluginSystem.use({
name: 'catalog-observer', permissions: ['events'],
install(api) { console.log(api.version); },
}, { grants: ['events'] });
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.ready
Espera instalaciones pendientes y expone sus fallos al bootstrap.
wu.pluginSystem.ready(): Promise<boolean>
- Parámetros: Sin argumentos.
- Retorno: true al terminar correctamente.
- Errores: Rechaza el primer error pendiente e incluye pendingPluginErrors.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No desinstala plugins exitosos.
await wu.pluginSystem.ready();
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.uninstall
Retira un plugin y su autoridad asociada.
wu.pluginSystem.uninstall(name): Promise<boolean>
- Parámetros: Nombre exacto del plugin.
- Retorno: Booleano de desinstalación.
- Errores: Uninstall puede fallar; consulta el error y los diagnósticos.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Invoca el hook uninstall y libera hooks/listeners propiedad del plugin.
await wu.pluginSystem.uninstall('catalog-observer');
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.getPlugin
Consulta la definición de un plugin instalado.
wu.pluginSystem.getPlugin(name): WuPlugin | undefined
- Parámetros: Nombre exacto.
- Retorno: Plugin o undefined.
- Errores: No existe hasta completar la instalación.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos nuevos.
console.log(wu.pluginSystem.getPlugin('catalog-observer')?.name);
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.getStats
Enumera plugins, permisos concedidos y hooks activos.
wu.pluginSystem.getStats(): object
- Parámetros: Sin argumentos.
- Retorno: Objeto con totalPlugins, plugins y hooks.
- Errores: No verifica efectos externos del plugin.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos nuevos.
console.log(wu.pluginSystem.getStats());
Referencia: src/core/wu-plugin.js.
wu.pluginSystem.cleanup
Desinstala todos los plugins del sistema.
wu.pluginSystem.cleanup(): Promise<void>
- Parámetros: Sin argumentos.
- Retorno: Promesa cuando termina el recorrido de desinstalación.
- Errores: Los fallos siguen el contrato de uninstall.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Afecta a todos los plugins; pertenece al teardown del host.
await wu.pluginSystem.cleanup();
Referencia: src/core/wu-plugin.js.
wu.timelineReady
Carga el recorder antes de las primeras escrituras que quieras capturar.
wu.timelineReady(): Promise<unknown>
- Parámetros: Sin argumentos.
- Retorno: Instancia real del recorder; no es la facade chainable.
- Errores: Rechaza errores de descarga/import del chunk.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: wu.timeline.stop() retira observadores; clear reinicia el journal.
await wu.timelineReady();
wu.timeline.record();
Referencia: src/index.js.
wu.timeline.record
Inicia el journal desde el estado y apps actuales.
wu.timeline.record(options?: { snapshotEvery?: number; maxEntries?: number }): WuTimelineFacade
- Parámetros: Frecuencia de snapshots y límite de entradas opcionales.
- Retorno: WuTimelineFacade
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: stop() retira los taps.
await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 25, maxEntries: 500 });
La facade devuelve ella misma; el recorder real devuelve status. Sin timelineReady, la carga diferida puede perder escrituras iniciales.
Referencia: src/core/wu-timeline.js.
wu.timeline.stop
Detiene la captura manteniendo el journal para inspección.
wu.timeline.stop(): WuTimelineFacade
- Parámetros: Sin argumentos.
- Retorno: WuTimelineFacade
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Retira taps de store y bus.
wu.timeline.stop();
No detiene timers, requests ni procesos creados por las aplicaciones.
Referencia: src/core/wu-timeline.js.
wu.timeline.clear
Vacía el journal y toma la situación actual como nuevo baseline.
wu.timeline.clear(): WuTimelineFacade
- Parámetros: Sin argumentos.
- Retorno: WuTimelineFacade
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No sustituye stop si quieres dejar de grabar.
wu.timeline.clear();
No borra estado de negocio ni revierte efectos externos.
Referencia: src/core/wu-timeline.js.
wu.timeline.seek
Materializa una posición del journal en sus proyecciones.
wu.timeline.seek(position: number, options?: { store?: boolean; apps?: boolean; props?: boolean }): Promise<WuTimelineStatus>
- Parámetros: Índice 0..length; selecciona store/apps/props.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Vuelve a live para recuperar la posición final.
const status = await wu.timeline.seek(0, { store: true, apps: false, props: false });
No revierte HTTP, timers ni infraestructura. Las escrituras hechas en el pasado no crean una rama nueva.
Referencia: src/core/wu-timeline.js.
wu.timeline.live
Materializa el final del journal.
wu.timeline.live(): Promise<WuTimelineStatus>
- Parámetros: Sin argumentos.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Conserva el recorder hasta stop.
await wu.timeline.live();
Volver a live descarta cambios no registrados durante la posición histórica.
Referencia: src/core/wu-timeline.js.
wu.timeline.stepBack
Retrocede una posición del journal.
wu.timeline.stepBack(): Promise<WuTimelineStatus>
- Parámetros: Sin argumentos.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: stop libera la captura cuando termine la sesión.
await wu.timeline.stepBack();
Se limita a las proyecciones reproducibles del recorder.
Referencia: src/core/wu-timeline.js.
wu.timeline.stepForward
Avanza una posición del journal.
wu.timeline.stepForward(): Promise<WuTimelineStatus>
- Parámetros: Sin argumentos.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: stop libera la captura cuando termine la sesión.
await wu.timeline.stepForward();
No reproduce efectos externos de una acción.
Referencia: src/core/wu-timeline.js.
wu.timeline.export
Serializa entradas, snapshots y baseline de apps.
wu.timeline.export(): Promise<WuTimelineExport>
- Parámetros: Sin argumentos.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: El host decide dónde guardar/exportar el objeto.
const journal = await wu.timeline.export();
Puede contener estado de aplicación; no es una auditoría durable automática.
Referencia: src/core/wu-timeline.js.
wu.timeline.import
Carga un journal serializado para inspeccionarlo.
wu.timeline.import(journal: WuTimelineExport): Promise<WuTimelineStatus>
- Parámetros: Objeto de export compatible.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: Afecta al recorder; elige explícitamente la proyección posterior.
await wu.timeline.import(journal);
Valida procedencia del estado; importar no ejecuta un sandbox remoto.
Referencia: src/core/wu-timeline.js.
wu.timeline.ingest
Combina entradas con el orden del journal y un baseline común vacío.
wu.timeline.ingest(entries: WuTimelineEntry[]): Promise<WuTimelineStatus>
- Parámetros: Entradas con reloj Lamport e identidad de sitio.
- Retorno: Promise
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No abre ni autentica un transporte.
await wu.timeline.ingest(remoteEntries);
El merge no materializa por sí mismo todo el estado en UI; requiere una base compartida y reglas de proyección.
Referencia: src/core/wu-timeline.js.
wu.timeline.entries
Lee las entradas que conserva el recorder.
wu.timeline.entries(): WuTimelineEntry[]
- Parámetros: Sin argumentos.
- Retorno: WuTimelineEntry[]
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos.
console.table(wu.timeline.entries());
El array se copia superficialmente; no lo uses para mutar el recorder.
Referencia: src/core/wu-timeline.js.
wu.timeline.status
Consulta captura, posición, relojes y capacidad ocupada.
wu.timeline.status(): WuTimelineStatus
- Parámetros: Sin argumentos.
- Retorno: WuTimelineStatus
- Errores: La familia asíncrona puede rechazar errores de chunk, formato o materialización.
- Permisos: Host; la facade scoped no expone administración global.
- Limpieza: No instala recursos.
console.log(wu.timeline.status());
loaded indica si el chunk ya está disponible; no garantiza que esté grabando.
Referencia: src/core/wu-timeline.js.