外观
Bridge
Bridge 面向 App 内嵌 WebView,提供预置基础桥、项目自定义调用和客户端事件监听。只有一个创建入口 createBridge(),基础方法直接放在实例上。
基础桥
ts
import { createBridge } from '@freenotes/web-runtime';
const bridge = createBridge({ timeoutMs: 3000 });
const config = await bridge.getConfig();
config?.appVersion;
await bridge.goBack();
await bridge.closePage({ reason: 'completed' });| 方法 | 返回值 | Native 方法 |
|---|---|---|
getConfig(options?) | Promise<BridgeConfig | undefined> | configAction |
goBack(options?) | Promise<void> | goBack |
closePage(payload?, options?) | Promise<BridgeClosePageResult | undefined> | closePage |
配置中的 app_version、device_model_identifier、device_type、region_code 转换为 appVersion、deviceModelIdentifier、deviceType、regionCode;environment、platform 保持原名,未知扩展字段保留。已声明配置字段必须是 string,关闭结果中的 closed 必须是 boolean;无效数据 reject host 错误。成功但宿主未返回 data 时,配置和关闭结果为 undefined。
基础方法复用同一 adapter、超时与错误机制。项目自定义契约不会覆盖或移除基础方法。
项目自定义调用与事件
ts
import { createBridge } from '@freenotes/web-runtime';
interface ProjectMethods {
openDocument: {
input: { documentId: string };
output: void;
};
}
interface ProjectEvents {
resume: { source: string };
}
const bridge = createBridge<ProjectMethods, ProjectEvents>();
await bridge.call('openDocument', { documentId: 'doc-1' });
const subscription = bridge.on('resume', (payload) => {
console.info('页面恢复来源', payload.source);
});
subscription.dispose();call 表示网页请求 Native 执行操作并等待响应;on 表示监听 Native 通知。自定义方法保留在项目类型表中,不动态挂载到实例。方法名决定 input/output,事件名决定 payload,拼写或参数类型不匹配会报类型错误。不传类型表时允许任意名称,数据默认为 unknown。
这些类型表提供编译期约束;外部数据仍需业务验证。泛型不能替代运行时校验。当前没有用于 Native 向网页请求业务返回值的 register API,on 回调的返回值不会作为业务结果发回 Native。
默认 App 适配
未传 adapter 时,库使用 App 的 DSBridge 3 通信和回包协议。创建实例不会读取或修改宿主、发送请求或注册监听,第一次 call / 基础方法 / on 执行时才访问 Native。普通浏览器和 SSR 可创建实例;实际操作缺少宿主时会报 unavailable 错误。宿主后续注入后,同一实例可以再次尝试调用。
需要核对宿主签名、回包格式或与已有 SDK 组合事件时,阅读 Bridge 进阶。
自定义 adapter 与浏览器测试
自定义 adapter 完全替换默认适配,call 必须返回已解码数据并通过 reject 表达失败,on 必须返回清理函数或 { dispose() }。库不会再按 App 协议解包自定义 adapter 的输出,也不会解析其事件 payload。基础方法仍验证对应数据并进行字段转换;其他宿主需实现这些基础方法对应的协议。
创建时捕获 adapter 方法和默认超时,保留方法的 receiver。之后替换原配置中的方法不会改变已有实例。adapter 内部状态仍由其实现管理。
浏览器中可以显式注入 mock:
ts
import { createBridge } from '@freenotes/web-runtime';
const bridge = createBridge({
adapter: {
call(method) {
if (method === 'configAction')
return Promise.resolve({ app_version: 'test', platform: 'browser' });
return Promise.reject(new Error(`Unsupported mock method: ${method}`));
}
}
});
const config = await bridge.getConfig();包含类型化调用、事件派发及订阅清理的完整浏览器示例见 基础示例。
错误与超时
默认超时 3000ms,基础方法 options 或 call(method, payload, { timeoutMs }) 可覆盖。超时只结束本次等待,无法撤销 Native 已经执行的动作。默认 adapter 会清理已完成或超时请求的回调闭包,迟到回调不会再次交付结果。
ts
import { BridgeError, createBridge } from '@freenotes/web-runtime';
const bridge = createBridge();
try {
await bridge.goBack();
} catch (error) {
if (error instanceof BridgeError) console.error(error.kind, error.cause);
else throw error;
}基础方法和 call 失败 reject BridgeError。kind 区分 unavailable、invalid-input、timeout、transport、host 和 subscription;code 为 ERR_BRIDGE_*,hostCode 保留 App 业务错误码,cause 保留失败数据或原始异常。配置无效时 factory 抛 TypeError;on 的非法名称或 handler 抛 TypeError,其它订阅或释放失败同步抛 BridgeError。