@kg-ui/widget-runtime
v1.0.0
Published
智星 Widget 运行时 - iframe 沙盒和生命周期管理
Readme
@zhixing/widget-runtime
智星运行时 Widget 管理包 - 提供安全的 iframe 沙盒和生命周期管理功能。
📋 功能特性
- 安全沙盒: 基于 iframe 的安全执行环境
- 生命周期管理: 完整的 Widget 生命周期控制
- Bridge 通信: 安全的父子窗口通信机制
- 状态管理: 双向状态同步和更新
- 错误处理: 完善的错误恢复机制
- 资源管理: 自动资源清理和内存管理
🏗️ 核心组件
Runtime 运行时
mount.ts- Widget 挂载和实例管理lifecycle.ts- 生命周期事件处理createIframe.ts- 安全 iframe 创建
Bridge 通信桥接
openaiBridge.ts- 父子窗口通信核心- 详细架构说明: OpenAI Bridge 架构详解
Security 安全机制
networkControl.ts- 网络访问控制storageIsolation.ts- 存储沙盒隔离threatDetection.ts- 安全威胁检测
Types 类型定义
widget.ts- Widget 相关类型定义
Errors 错误处理
LifecycleError.ts- 生命周期相关错误SecurityError.ts- 安全相关错误
🚀 快速开始
安装
pnpm add @zhixing/widget-runtime基本使用
import { DefaultMountManager } from '@zhixing/widget-runtime';
// 创建挂载管理器
const mountManager = new DefaultMountManager();
// 挂载 Widget
const widgetInstance = await mountManager.mount(container, {
srcdoc: '<html>...</html>',
initialState: { initialized: true },
toolOutput: {
structuredContent: { /* ... */ },
metadata: { timestamp: Date.now() }
}
});
// 更新 Widget
await mountManager.updateWidget(widgetInstance, {
widgetState: { currentPage: 2 }
});
// 卸载 Widget
await mountManager.unmount(widgetInstance);📡 Bridge 通信机制
Widget 运行时使用 OpenAI Bridge 实现安全的父子窗口通信:
Widget 内部 API
// 访问工具输出数据
const data = window.openai.toolOutput.structuredContent;
// 更新 Widget 状态
window.openai.setWidgetState({
currentPage: 2,
selectedItems: ['item1', 'item2']
});
// 监听 Bridge 就绪事件
window.addEventListener('openai-bridge-ready', (event) => {
console.log('Bridge 已就绪:', event.detail.openai);
initializeWidget();
});父窗口管理
import { DefaultBridgeManager } from '@zhixing/widget-runtime';
const bridgeManager = new DefaultBridgeManager();
// 注入 Bridge 到 iframe
await bridgeManager.injectBridge(
iframe,
toolOutput,
(patch) => {
// 处理状态更新
console.log('Widget 状态更新:', patch);
}
);🛡️ 安全特性
沙盒隔离
- iframe sandbox 属性限制
- CSP (Content Security Policy) 保护
- 网络访问控制
- 存储隔离机制
数据保护
- 深度只读代理保护传入数据
- 状态更新验证和过滤
- 函数注入防护
- 消息来源严格验证
错误恢复
- 超时机制 (15秒)
- 自动重试和降级
- 资源清理和内存管理
- 详细错误日志
🔄 生命周期管理
Widget 支持完整的生命周期事件:
// 生命周期事件
await lifecycleManager.onInit(widget); // 初始化
await lifecycleManager.onRender(widget); // 渲染
await lifecycleManager.onUpdate(widget, updates); // 更新
await lifecycleManager.onDestroy(widget); // 销毁生命周期状态
CREATED- 已创建INITIALIZING- 初始化中INITIALIZED- 已初始化RENDERING- 渲染中RENDERED- 已渲染UPDATING- 更新中DESTROYING- 销毁中DESTROYED- 已销毁
📊 实例管理
创建和管理实例
// 获取活跃实例
const activeInstances = mountManager.getActiveInstances();
// 获取特定实例
const instance = mountManager.getInstance('widget-id');
// 检查实例隔离状态
const isIsolated = mountManager.isInstanceIsolated('widget-id');
// 清理所有实例
await mountManager.cleanup_all();实例操作
// Widget 实例方法
await widgetInstance.update({
widgetState: { newData: 'value' }
});
await widgetInstance.destroy();
const currentState = widgetInstance.getState();🔧 配置选项
Widget 配置
interface WidgetConfig {
src?: string; // iframe src URL
srcdoc?: string; // iframe srcdoc 内容
initialState?: any; // 初始状态
toolOutput?: WidgetInput; // 工具输出数据
}iframe 配置
interface IframeConfig {
sandbox: string[]; // 沙盒权限
csp: string; // 内容安全策略
src?: string; // 源 URL
srcdoc?: string; // 内联内容
}📝 开发指南
创建自定义 Widget
- 实现 Widget HTML 内容
- 添加 Bridge 通信逻辑
- 处理生命周期事件
- 实现状态管理
调试技巧
- 启用详细日志记录
- 使用浏览器开发者工具
- 检查 iframe 沙盒设置
- 监控消息传递过程
性能优化
- 合理设置超时时间
- 及时清理不需要的资源
- 使用高效的状态更新策略
- 避免频繁的 DOM 操作
🧪 测试
# 运行单元测试
pnpm test
# 运行监听模式测试
pnpm test --watch
# 生成覆盖率报告
pnpm test --coverage📚 相关文档
🤝 贡献
欢迎提交 Issue 和 Pull Request 来改进这个包。
📄 许可证
MIT License
