WU / DOCSUNIVERSAL MICROFRONTENDS
EN

Hooks, plugins, and timeline reference

Extend lifecycle, install plugins with grants, and control time projections while distinguishing their authorities.

A hook changes the lifecycle flow; a plugin groups setup, permissions, and cleanup; timeline keeps a projection journal. Each mechanism has an owner and a way to end its activity.

Intercepting a phase

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();

Available phases are before/after Init, Load, Mount, Update, Unmount, and Destroy. Higher priority runs first. Omitting next() cancels the chain; failOpen: true allows continuation after middleware failure. A UI guard does not replace role controls or core grants.

Granting authority to a plugin

Plugin permissions are mount, events, store, apps, config, and unsafe. A plugin requests these names, and the host grants options.grants during installation. Do not reuse store.read or rpc.call as plugin grants: those belong to application contracts.

Await pluginSystem.use or pluginSystem.ready before depending on setup. Installation from an asynchronous factory also participates in this startup. A plugin executes host code; its reduced API does not remove privileges captured in closures.

Recording before writing

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();

The wu.timeline facade retains chainable methods for synchronous controls. The real object returned by timelineReady has different return values; use the facade in this reference’s examples. Seek rematerializes store, props, and composition according to options; it does not rewind networks, timers, or infrastructure.

wu.hooks.use

Installs lifecycle middleware with priority and individual cleanup.

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

  • Parameters: Valid phase, middleware(context,next); options: name, priority, failOpen.
  • Returns: Unsubscribe function; the TypeScript declaration says void.
  • Errors: Unknown phase or invalid callback throws; omitting next cancels the chain.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: stop() removes only that middleware.
const stop = wu.hooks.use('beforeMount', async (context, next) => {
  console.log(context.appName);
  await next();
}, { name: 'mount-log', priority: 10 });

Reference: src/core/wu-hooks.js.

wu.hooks.useMultiple

Installs the same middleware in several phases.

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

  • Parameters: Phase array; use a stable name to identify each derived registration.
  • Returns: Combined cleanup.
  • Errors: Every phase must exist; registration is not atomic if a later phase fails.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: stop() removes the created installations.
const stop = wu.hooks.useMultiple(['beforeMount', 'beforeUnmount'], async (ctx, next) => {
  await next();
}, { name: 'trace' });

Reference: src/core/wu-hooks.js.

wu.hooks.remove

Removes middleware identified by phase and name.

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

  • Parameters: phase and registration name.
  • Returns: void; absence does not throw.
  • Errors: Duplicate names make removal ambiguous; prefer individual cleanup.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no new resources.
wu.hooks.remove('beforeMount', 'mount-log');

Reference: src/core/wu-hooks.js.

wu.hooks.getHooks

Queries installed middleware metadata.

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

  • Parameters: Optional phase.
  • Returns: Without a phase: metadata map; with a phase: registration array.
  • Errors: With a phase, returns internal registrations; do not mutate them as a configuration API.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no new resources.
console.log(wu.hooks.getHooks());

Reference: src/core/wu-hooks.js.

wu.hooks.getStats

Queries hook distribution and execution records.

wu.hooks.getStats(): object

  • Parameters: No arguments.
  • Returns: Metrics object.
  • Errors: The execution log has limited capacity.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no new resources.
console.log(wu.hooks.getStats());

Reference: src/core/wu-hooks.js.

wu.hooks.cleanup

Removes middleware from one or every phase.

wu.hooks.cleanup(phase?): void

  • Parameters: Optional phase; omitting it also empties the execution log.
  • Returns: void.
  • Errors: Does not itself cancel a callback already running.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Releases registrations; resources created by callbacks need their own cleanup.
wu.hooks.cleanup('beforeMount');

Reference: src/core/wu-hooks.js.

createSimpleHook

Converts a callback into middleware that continues the chain.

createSimpleHook(fn): Function

  • Parameters: fn(context) may be asynchronous.
  • Returns: async(context,next) middleware.
  • Errors: Callback errors follow the factory and chain policy.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Install with hooks.use and retain that registration’s cleanup.
import { createSimpleHook } from 'wu-framework';
const middleware = createSimpleHook(ctx => console.log(ctx.appName));

Awaits the callback, then invokes next.

Reference: src/core/wu-hooks.js.

createConditionalHook

Executes a callback if the condition is true, then continues.

createConditionalHook(condition, fn): Function

  • Parameters: condition(context) and fn(context).
  • Returns: async(context,next) middleware.
  • Errors: Callback errors follow the factory and chain policy.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Install with hooks.use and retain that registration’s cleanup.
import { createConditionalHook } from 'wu-framework';
const middleware = createConditionalHook(ctx => ctx.appName === 'catalog', ctx => console.log(ctx));

The condition is not a cancellation guard: a false condition continues the chain.

Reference: src/core/wu-hooks.js.

createGuardHook

Continues the chain only when the guard allows it.

createGuardHook(shouldContinue): Function

  • Parameters: shouldContinue(context), synchronous or promise.
  • Returns: async(context,next) middleware.
  • Errors: Callback errors follow the factory and chain policy.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Install with hooks.use and retain that registration’s cleanup.
import { createGuardHook } from 'wu-framework';
const middleware = createGuardHook(ctx => ctx.appName !== 'disabled-app');

If it returns false, it does not call next; it does not replace grants or server authorization.

Reference: src/core/wu-hooks.js.

createTransformHook

Transforms the context received by the next middleware.

createTransformHook(transformer): Function

  • Parameters: transformer(context) returns context data.
  • Returns: async(context,next) middleware.
  • Errors: Callback errors follow the factory and chain policy.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Install with hooks.use and retain that registration’s cleanup.
import { createTransformHook } from 'wu-framework';
const middleware = createTransformHook(ctx => ({ ...ctx, traceLabel: 'catalog' }));

This does not configure the core beyond fields consumed by that lifecycle.

Reference: src/core/wu-hooks.js.

createTimedHook

Limits how long middleware waits for a callback.

createTimedHook(fn, timeout?: number): Function

  • Parameters: fn(context); default timeout 5000 ms.
  • Returns: async(context,next) middleware.
  • Errors: Callback errors follow the factory and chain policy.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Install with hooks.use and retain that registration’s cleanup.
import { createTimedHook } from 'wu-framework';
const middleware = createTimedHook(async ctx => console.log(ctx.appName), 1000);

A failure or timeout is logged and the chain continues; original work is not automatically aborted.

Reference: src/core/wu-hooks.js.

createPlugin

Builds a plugin with a name, requested permissions, and callbacks.

createPlugin(config): WuPlugin

  • Parameters: config with name; optional install/uninstall and hooks.
  • Returns: Plugin object; creating does not install.
  • Errors: Invalid name/config may throw.
  • Permissions: The plugin requests permissions; the host grants them when calling use.
  • Cleanup: Install with pluginSystem.use and remove with uninstall.
import { createPlugin } from 'wu-framework';
const plugin = createPlugin({ name: 'catalog-observer', permissions: ['events'], install(api) { console.log(api.version); } });

Reference: src/core/wu-plugin.js.

wu.pluginSystem.use

Installs a plugin and awaits setup before considering it available.

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

  • Parameters: Plugin or async factory; options.grants and compatibility configure authority.
  • Returns: true when installed; rejects validation/setup failures.
  • Errors: Required permissions without grants, duplicates, and install errors may reject.
  • Permissions: Plugin permissions: mount, events, store, apps, config, unsafe; distinct from app capabilities.
  • Cleanup: await uninstall(name) revokes its API and runs cleanup.
await wu.pluginSystem.use({
  name: 'catalog-observer', permissions: ['events'],
  install(api) { console.log(api.version); },
}, { grants: ['events'] });

Reference: src/core/wu-plugin.js.

wu.pluginSystem.ready

Awaits pending installations and exposes their failures to bootstrap.

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

  • Parameters: No arguments.
  • Returns: true on successful completion.
  • Errors: Rejects the first pending error and includes pendingPluginErrors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Does not uninstall successful plugins.
await wu.pluginSystem.ready();

Reference: src/core/wu-plugin.js.

wu.pluginSystem.uninstall

Removes a plugin and its associated authority.

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

  • Parameters: Exact plugin name.
  • Returns: Uninstallation boolean.
  • Errors: Uninstall may fail; inspect the error and diagnostics.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Invokes the uninstall hook and releases plugin-owned hooks/listeners.
await wu.pluginSystem.uninstall('catalog-observer');

Reference: src/core/wu-plugin.js.

wu.pluginSystem.getPlugin

Queries an installed plugin’s definition.

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

  • Parameters: Exact name.
  • Returns: Plugin or undefined.
  • Errors: Does not exist until installation completes.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no new resources.
console.log(wu.pluginSystem.getPlugin('catalog-observer')?.name);

Reference: src/core/wu-plugin.js.

wu.pluginSystem.getStats

Lists plugins, granted permissions, and active hooks.

wu.pluginSystem.getStats(): object

  • Parameters: No arguments.
  • Returns: Object with totalPlugins, plugins, and hooks.
  • Errors: Does not verify plugin external effects.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no new resources.
console.log(wu.pluginSystem.getStats());

Reference: src/core/wu-plugin.js.

wu.pluginSystem.cleanup

Uninstalls every plugin in the system.

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

  • Parameters: No arguments.
  • Returns: Promise resolving when uninstallation traversal finishes.
  • Errors: Failures follow the uninstall contract.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Affects all plugins; belongs to host teardown.
await wu.pluginSystem.cleanup();

Reference: src/core/wu-plugin.js.

wu.timelineReady

Loads the recorder before the first writes you want to capture.

wu.timelineReady(): Promise<unknown>

  • Parameters: No arguments.
  • Returns: Actual recorder instance; not the chainable facade.
  • Errors: Rejects chunk download/import errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: wu.timeline.stop() removes observers; clear resets the journal.
await wu.timelineReady();
wu.timeline.record();

Reference: src/index.js.

wu.timeline.record

Starts the journal from current state and apps.

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

  • Parameters: Optional snapshot frequency and entry limit.
  • Returns: WuTimelineFacade
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: stop() removes taps.
await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 25, maxEntries: 500 });

The facade returns itself; the actual recorder returns status. Without timelineReady, deferred loading may miss initial writes.

Reference: src/core/wu-timeline.js.

wu.timeline.stop

Stops capture while retaining the journal for inspection.

wu.timeline.stop(): WuTimelineFacade

  • Parameters: No arguments.
  • Returns: WuTimelineFacade
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Removes store and bus taps.
wu.timeline.stop();

Does not stop timers, requests, or processes created by applications.

Reference: src/core/wu-timeline.js.

wu.timeline.clear

Empties the journal and takes the current situation as the new baseline.

wu.timeline.clear(): WuTimelineFacade

  • Parameters: No arguments.
  • Returns: WuTimelineFacade
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Does not replace stop if you want to stop recording.
wu.timeline.clear();

Does not delete business state or reverse external effects.

Reference: src/core/wu-timeline.js.

wu.timeline.seek

Materializes a journal position in its projections.

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

  • Parameters: Index 0..length; selects store/apps/props.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Return to live to recover the final position.
const status = await wu.timeline.seek(0, { store: true, apps: false, props: false });

Does not reverse HTTP, timers, or infrastructure. Writes made in the past do not create a new branch.

Reference: src/core/wu-timeline.js.

wu.timeline.live

Materializes the end of the journal.

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

  • Parameters: No arguments.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Retains the recorder until stop.
await wu.timeline.live();

Returning to live discards unrecorded changes made at the historical position.

Reference: src/core/wu-timeline.js.

wu.timeline.stepBack

Moves back one journal position.

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

  • Parameters: No arguments.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: stop releases capture when the session ends.
await wu.timeline.stepBack();

Limited to the recorder’s reproducible projections.

Reference: src/core/wu-timeline.js.

wu.timeline.stepForward

Moves forward one journal position.

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

  • Parameters: No arguments.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: stop releases capture when the session ends.
await wu.timeline.stepForward();

Does not replay an action’s external effects.

Reference: src/core/wu-timeline.js.

wu.timeline.export

Serializes entries, snapshots, and the app baseline.

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

  • Parameters: No arguments.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: The host decides where to save/export the object.
const journal = await wu.timeline.export();

May contain application state; not an automatic durable audit.

Reference: src/core/wu-timeline.js.

wu.timeline.import

Loads a serialized journal for inspection.

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

  • Parameters: Compatible export object.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Affects the recorder; explicitly choose the subsequent projection.
await wu.timeline.import(journal);

Validate state provenance; importing does not execute a remote sandbox.

Reference: src/core/wu-timeline.js.

wu.timeline.ingest

Merges entries using journal order and a shared empty baseline.

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

  • Parameters: Entries with Lamport clock and site identity.
  • Returns: Promise
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Does not open or authenticate transport.
await wu.timeline.ingest(remoteEntries);

Merging does not itself materialize all UI state; it requires a shared baseline and projection rules.

Reference: src/core/wu-timeline.js.

wu.timeline.entries

Reads entries retained by the recorder.

wu.timeline.entries(): WuTimelineEntry[]

  • Parameters: No arguments.
  • Returns: WuTimelineEntry[]
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no resources.
console.table(wu.timeline.entries());

The array is shallow-copied; do not use it to mutate the recorder.

Reference: src/core/wu-timeline.js.

wu.timeline.status

Queries capture, position, clocks, and used capacity.

wu.timeline.status(): WuTimelineStatus

  • Parameters: No arguments.
  • Returns: WuTimelineStatus
  • Errors: The asynchronous family may reject chunk, format, or materialization errors.
  • Permissions: Host; the scoped facade does not expose global administration.
  • Cleanup: Installs no resources.
console.log(wu.timeline.status());

loaded indicates whether the chunk is available; it does not guarantee recording is active.

Reference: src/core/wu-timeline.js.

BUILD WU WITH US

Found a bug? Have an idea?

Your experience improves WU. Tell us what went wrong or help support its development.