Hooks、插件与 timeline 参考
扩展生命周期、使用 grants 安装插件并控制时间投影,区分各自权限。
Hook 修改生命周期流程;插件组织 setup、权限和 cleanup;timeline 保留投影 journal。每种机制都有所属者和结束活动的方式。
拦截阶段
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();
可用阶段是 Init、Load、Mount、Update、Unmount 和 Destroy 的 before/after。优先级越高越先执行。省略 next() 取消链;failOpen: true 允许中间件失败后继续。界面 guard 不能替代 core 角色控制或 grants。
向插件授予权限
插件权限是 mount、events、store、apps、config 和 unsafe。插件申请这些名称,宿主安装时通过 options.grants 授予。不要把 store.read 或 rpc.call 用作插件 grants,它们属于应用契约。
依赖 setup 前,等待 pluginSystem.use 或 pluginSystem.ready。异步 factory 安装也参与启动过程。插件执行宿主代码;缩减 API 不会消除闭包已捕获的权限。
先记录,再写入
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();
wu.timeline facade 保留可链式调用的方法用于同步控制。timelineReady 返回的真实对象具有不同返回值;本参考示例使用 facade。Seek 按选项重新生成 store、props 和组合,不回退网络、timer 或基础设施。
wu.hooks.use
安装带优先级和独立清理的生命周期中间件。
wu.hooks.use(phase, middleware, options?): () => void
- 参数: 有效阶段、middleware(context,next);options:name、priority、failOpen。
- 返回值: 取消函数;TypeScript 声明为 void。
- 错误: 未知阶段或无效回调会抛出;省略 next 取消链。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: stop() 只移除此中间件。
const stop = wu.hooks.use('beforeMount', async (context, next) => {
console.log(context.appName);
await next();
}, { name: 'mount-log', priority: 10 });
参考:src/core/wu-hooks.js.
wu.hooks.useMultiple
将同一中间件安装到多个阶段。
wu.hooks.useMultiple(phases, middleware, options?): () => void
- 参数: 阶段数组;使用稳定 name 标识各派生注册。
- 返回值: 组合 cleanup。
- 错误: 每个阶段必须存在;后续阶段失败时,注册并非原子操作。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: stop() 移除本次创建的安装。
const stop = wu.hooks.useMultiple(['beforeMount', 'beforeUnmount'], async (ctx, next) => {
await next();
}, { name: 'trace' });
参考:src/core/wu-hooks.js.
wu.hooks.remove
按阶段和名称移除中间件。
wu.hooks.remove(phase, name): void
- 参数: phase 和注册 name。
- 返回值: void;不存在时不抛出。
- 错误: 重复名称会使移除存在歧义,优先使用独立 cleanup。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装新资源。
wu.hooks.remove('beforeMount', 'mount-log');
参考:src/core/wu-hooks.js.
wu.hooks.getHooks
查询已安装中间件元数据。
wu.hooks.getHooks(phase?): object | object[]
- 参数: 可选阶段。
- 返回值: 无阶段时返回元数据映射,有阶段时返回注册数组。
- 错误: 指定阶段会返回内部记录;不要通过修改它们配置 API。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装新资源。
console.log(wu.hooks.getHooks());
参考:src/core/wu-hooks.js.
wu.hooks.getStats
查询 hooks 分布和执行记录。
wu.hooks.getStats(): object
- 参数: 无参数。
- 返回值: 指标对象。
- 错误: 执行日志容量有限。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装新资源。
console.log(wu.hooks.getStats());
参考:src/core/wu-hooks.js.
wu.hooks.cleanup
移除一个或全部阶段的中间件。
wu.hooks.cleanup(phase?): void
- 参数: 可选阶段;省略时还清空执行日志。
- 返回值: void。
- 错误: 不会自行取消已在执行的回调。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 释放注册;回调创建的资源需要自己的 cleanup。
wu.hooks.cleanup('beforeMount');
参考:src/core/wu-hooks.js.
createSimpleHook
将回调转换为继续执行链的中间件。
createSimpleHook(fn): Function
- 参数: fn(context) 可以是异步函数。
- 返回值: async(context,next) 中间件。
- 错误: 回调错误遵循 factory 和链的策略。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 用 hooks.use 安装,并保存该注册的 cleanup。
import { createSimpleHook } from 'wu-framework';
const middleware = createSimpleHook(ctx => console.log(ctx.appName));
等待回调后再调用 next。
参考:src/core/wu-hooks.js.
createConditionalHook
条件为真时执行回调,然后继续。
createConditionalHook(condition, fn): Function
- 参数: condition(context) 和 fn(context)。
- 返回值: async(context,next) 中间件。
- 错误: 回调错误遵循 factory 和链的策略。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 用 hooks.use 安装,并保存该注册的 cleanup。
import { createConditionalHook } from 'wu-framework';
const middleware = createConditionalHook(ctx => ctx.appName === 'catalog', ctx => console.log(ctx));
条件不是取消 guard;条件为假时仍继续执行链。
参考:src/core/wu-hooks.js.
createGuardHook
只有 guard 允许时才继续执行链。
createGuardHook(shouldContinue): Function
- 参数: shouldContinue(context),同步值或 Promise。
- 返回值: async(context,next) 中间件。
- 错误: 回调错误遵循 factory 和链的策略。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 用 hooks.use 安装,并保存该注册的 cleanup。
import { createGuardHook } from 'wu-framework';
const middleware = createGuardHook(ctx => ctx.appName !== 'disabled-app');
返回 false 时不调用 next;不能替代 grants 或服务器授权。
参考:src/core/wu-hooks.js.
createTransformHook
转换传给下一中间件的上下文。
createTransformHook(transformer): Function
- 参数: transformer(context) 返回上下文数据。
- 返回值: async(context,next) 中间件。
- 错误: 回调错误遵循 factory 和链的策略。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 用 hooks.use 安装,并保存该注册的 cleanup。
import { createTransformHook } from 'wu-framework';
const middleware = createTransformHook(ctx => ({ ...ctx, traceLabel: 'catalog' }));
不等同于配置该生命周期实际读取字段之外的 core。
参考:src/core/wu-hooks.js.
createTimedHook
限制中间件等待回调的时间。
createTimedHook(fn, timeout?: number): Function
- 参数: fn(context);默认超时 5000 ms。
- 返回值: async(context,next) 中间件。
- 错误: 回调错误遵循 factory 和链的策略。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 用 hooks.use 安装,并保存该注册的 cleanup。
import { createTimedHook } from 'wu-framework';
const middleware = createTimedHook(async ctx => console.log(ctx.appName), 1000);
失败或超时会记录日志并继续链;原始工作不会自动中止。
参考:src/core/wu-hooks.js.
createPlugin
创建包含名称、权限申请和回调的插件。
createPlugin(config): WuPlugin
- 参数: 含 name 的 config;install/uninstall 和 hooks 可选。
- 返回值: 插件对象;创建不等于安装。
- 错误: 无效名称或配置可能抛出。
- 权限: 插件申请权限,宿主调用 use 时授予。
- 清理: 用 pluginSystem.use 安装,用 uninstall 移除。
import { createPlugin } from 'wu-framework';
const plugin = createPlugin({ name: 'catalog-observer', permissions: ['events'], install(api) { console.log(api.version); } });
参考:src/core/wu-plugin.js.
wu.pluginSystem.use
安装插件并等待 setup 完成后才将其视为可用。
wu.pluginSystem.use(pluginOrFactory, options?): Promise<boolean>
- 参数: 插件或 async factory;options.grants 和 compatibility 配置权限。
- 返回值: 安装完成返回 true;验证/setup 失败时拒绝。
- 错误: 所需权限未获 grants、重复注册或 install 错误可能导致拒绝。
- 权限: 插件权限为 mount、events、store、apps、config、unsafe,与应用 capabilities 不同。
- 清理: await uninstall(name) 撤销 API 并执行 cleanup。
await wu.pluginSystem.use({
name: 'catalog-observer', permissions: ['events'],
install(api) { console.log(api.version); },
}, { grants: ['events'] });
参考:src/core/wu-plugin.js.
wu.pluginSystem.ready
等待待完成安装,并向启动过程报告失败。
wu.pluginSystem.ready(): Promise<boolean>
- 参数: 无参数。
- 返回值: 成功完成时为 true。
- 错误: 以首个待报告错误拒绝,并包含 pendingPluginErrors。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不卸载成功的插件。
await wu.pluginSystem.ready();
参考:src/core/wu-plugin.js.
wu.pluginSystem.uninstall
移除插件及其关联权限。
wu.pluginSystem.uninstall(name): Promise<boolean>
- 参数: 精确插件名称。
- 返回值: 表示卸载结果的布尔值。
- 错误: Uninstall 可能失败;请查看错误与诊断。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 调用 uninstall hook,并释放插件所属 hooks/listeners。
await wu.pluginSystem.uninstall('catalog-observer');
参考:src/core/wu-plugin.js.
wu.pluginSystem.getPlugin
查询已安装插件的定义。
wu.pluginSystem.getPlugin(name): WuPlugin | undefined
- 参数: 精确名称。
- 返回值: 插件或 undefined。
- 错误: 安装完成前不存在。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装新资源。
console.log(wu.pluginSystem.getPlugin('catalog-observer')?.name);
参考:src/core/wu-plugin.js.
wu.pluginSystem.getStats
列出插件、已授予权限和活动 hooks。
wu.pluginSystem.getStats(): object
- 参数: 无参数。
- 返回值: 包含 totalPlugins、plugins 和 hooks 的对象。
- 错误: 不验证插件外部副作用。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装新资源。
console.log(wu.pluginSystem.getStats());
参考:src/core/wu-plugin.js.
wu.pluginSystem.cleanup
卸载系统全部插件。
wu.pluginSystem.cleanup(): Promise<void>
- 参数: 无参数。
- 返回值: 卸载遍历完成后的 Promise。
- 错误: 失败遵循 uninstall 约定。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 影响所有插件,属于宿主 teardown。
await wu.pluginSystem.cleanup();
参考:src/core/wu-plugin.js.
wu.timelineReady
在需要捕获的首次写入前加载 recorder。
wu.timelineReady(): Promise<unknown>
- 参数: 无参数。
- 返回值: recorder 真实实例,不是可链式调用的 facade。
- 错误: chunk 下载或导入错误会拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: wu.timeline.stop() 移除观察者;clear 重置 journal。
await wu.timelineReady();
wu.timeline.record();
参考:src/index.js.
wu.timeline.record
从当前状态和应用开始 journal。
wu.timeline.record(options?: { snapshotEvery?: number; maxEntries?: number }): WuTimelineFacade
- 参数: 可选快照频率和条目上限。
- 返回值: WuTimelineFacade
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: stop() 移除 taps。
await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 25, maxEntries: 500 });
facade 返回自身,真实 recorder 返回 status。未调用 timelineReady 时,延迟加载可能丢失初始写入。
参考:src/core/wu-timeline.js.
wu.timeline.stop
停止捕获,保留 journal 供检查。
wu.timeline.stop(): WuTimelineFacade
- 参数: 无参数。
- 返回值: WuTimelineFacade
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 移除 store 和总线的 taps。
wu.timeline.stop();
不停止应用创建的 timers、requests 或进程。
参考:src/core/wu-timeline.js.
wu.timeline.clear
清空 journal,将当前情况作为新 baseline。
wu.timeline.clear(): WuTimelineFacade
- 参数: 无参数。
- 返回值: WuTimelineFacade
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 想停止记录时,不能用它替代 stop。
wu.timeline.clear();
不删除业务状态,也不撤销外部副作用。
参考:src/core/wu-timeline.js.
wu.timeline.seek
将 journal 某个位置重建为对应投影。
wu.timeline.seek(position: number, options?: { store?: boolean; apps?: boolean; props?: boolean }): Promise<WuTimelineStatus>
- 参数: 索引 0..length;选择 store/apps/props。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 返回 live 以恢复最终位置。
const status = await wu.timeline.seek(0, { store: true, apps: false, props: false });
不回退 HTTP、timers 或基础设施。在过去位置写入不会创建新分支。
参考:src/core/wu-timeline.js.
wu.timeline.live
重建 journal 末尾状态。
wu.timeline.live(): Promise<WuTimelineStatus>
- 参数: 无参数。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: recorder 保留至 stop。
await wu.timeline.live();
返回 live 会丢弃历史位置期间未记录的变更。
参考:src/core/wu-timeline.js.
wu.timeline.stepBack
在 journal 中后退一个位置。
wu.timeline.stepBack(): Promise<WuTimelineStatus>
- 参数: 无参数。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 会话结束时,stop 释放捕获。
await wu.timeline.stepBack();
仅限 recorder 可重现的投影。
参考:src/core/wu-timeline.js.
wu.timeline.stepForward
在 journal 中前进一个位置。
wu.timeline.stepForward(): Promise<WuTimelineStatus>
- 参数: 无参数。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 会话结束时,stop 释放捕获。
await wu.timeline.stepForward();
不重放 action 的外部副作用。
参考:src/core/wu-timeline.js.
wu.timeline.export
序列化条目、快照和应用 baseline。
wu.timeline.export(): Promise<WuTimelineExport>
- 参数: 无参数。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 宿主决定对象的保存或导出位置。
const journal = await wu.timeline.export();
可能包含应用状态,不是自动持久审计。
参考:src/core/wu-timeline.js.
wu.timeline.import
加载序列化 journal 供检查。
wu.timeline.import(journal: WuTimelineExport): Promise<WuTimelineStatus>
- 参数: 兼容的 export 对象。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 影响 recorder;后续投影需显式选择。
await wu.timeline.import(journal);
验证状态来源;导入不会运行远程沙箱。
参考:src/core/wu-timeline.js.
wu.timeline.ingest
依据 journal 顺序合并条目,使用共同的空 baseline。
wu.timeline.ingest(entries: WuTimelineEntry[]): Promise<WuTimelineStatus>
- 参数: 带 Lamport 时钟和站点身份的条目。
- 返回值: Promise
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不打开或认证传输通道。
await wu.timeline.ingest(remoteEntries);
合并本身不会把全部状态呈现在 UI 中;需要共同基础和投影规则。
参考:src/core/wu-timeline.js.
wu.timeline.entries
读取 recorder 保留的条目。
wu.timeline.entries(): WuTimelineEntry[]
- 参数: 无参数。
- 返回值: WuTimelineEntry[]
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装资源。
console.table(wu.timeline.entries());
数组为浅复制,不要通过它修改 recorder。
参考:src/core/wu-timeline.js.
wu.timeline.status
查询捕获状态、位置、时钟和已用容量。
wu.timeline.status(): WuTimelineStatus
- 参数: 无参数。
- 返回值: WuTimelineStatus
- 错误: 异步方法可能因 chunk、格式或重建错误而拒绝。
- 权限: 宿主;scoped facade 不暴露全局管理。
- 清理: 不安装资源。
console.log(wu.timeline.status());
loaded 表示 chunk 是否可用,不保证正在记录。
参考:src/core/wu-timeline.js.