开发者文档/接口参考

Web SDK 参考

查阅 @trove/plugin-sdk 的请求、类型化服务、事件、取消和连接生命周期。

核对日期:2026 年 9 月 11 日

本页目录

安装与连接#

模板通过本地包提供 @trove/plugin-sdk。已有项目可按 SDK 接入步骤安装。本参考对应 SDK 0.1.0 与 Bridge 协议 v1。

ts
import { trove } from "@trove/plugin-sdk";

await trove.ready();
console.log(trove.context);

ready(): Promise<void> 只建立一次连接,后续调用共享连接。请求也会自动等待就绪。导入 SDK 是惰性的,可在 Host 外执行;普通浏览器中使用默认客户端或读取 context 会得到 bridge.host_unavailable

Context 字段类型与含义
curioIdcurioVersion当前 Curio 的 ID 和 Manifest 版本
instanceId当前 UI 窗口实例 ID
apiVersion1
mode"development""production"

Context 只读,由 Host 提供,不能通过请求参数伪造调用者身份。

请求与服务客户端#

ts
const host = await trove.call<{
  name: "Trove";
  version: string;
  platform: "macos";
  arch: string;
  protocol: 1;
}>("host.runtime", "getHostInfo", {}, { timeoutMs: 5_000 });

const storage = trove.service("host.storage");
await storage.call("set", { key: "theme", value: "system" });
API接口约定
call<TResult, TParams>(service, method, params?, options?)返回 Promise<TResult>,省略参数时发送 {}
service(serviceId)返回带 call(method, params?, options?)subscribe(...) 的客户端
service<TContract>(serviceId)根据 TypeScript 接口检查方法名、参数和结果类型
self.call(method, params?, options?)使用 @self 私有地址调用当前 Curio 的 Backend

泛型返回类型描述你的预期,不会在 Web SDK 中增加运行时校验。公共服务由 Host 根据 Contract 验证。SDK 提供通讯接口,没有 trove.fs.readText() 这样的专用能力方法。

ts
interface TextTools {
  uppercase(params: { text: string }): Promise<{ text: string }>;
}

const textTools = trove.service<TextTools>(
  "dev.example.text-tools.transformer",
);
const result = await textTools.call("uppercase", { text: "hello" });

此示例需要已安装的服务提供方,以及匹配的 services.requires 声明,详见服务接入trove.self 也要求真实 Backend 已实现目标方法;起始模板没有 Backend。

超时与取消#

CallOptionsSubscribeOptions 接受 timeoutMs?: numbersignal?: AbortSignal。SDK 默认请求超时为 30,000 ms。显式超时必须是有限数字,范围 1–2,147,483,647 ms;Host 或服务可能施加额外限制。

ts
const controller = new AbortController();
const request = trove.call(
  "host.runtime", "echo", { message: "hello" },
  { timeoutMs: 5_000, signal: controller.signal },
);
// Connect this to a cancel button or component cleanup when needed:
// controller.abort();
const result = await request;

可以把 controller.abort() 接到取消按钮或组件清理。超时与取消会拒绝 Promise,并在请求已发出时尽力发送 cancel 消息,但不会回滚已经完成的副作用。只重试可以安全重复的操作。

事件订阅与清理#

ts
const subscription = await trove.subscribe<{ taskId: string; progress: number }>(
  "dev.example.text-tools.transformer",
  "progress",
  { taskId: "demo" },
  (event) => console.log(event.progress),
);

// When the owning screen or task is finished:
await subscription.close();

提供方必须实现这个事件主题和 Contract。subscribe 返回 TroveSubscription,包含 id: stringclose(): Promise<void>。重复调用 close() 是安全的。AbortSignal 可取消订阅建立过程,也能在建立后关闭订阅。组件卸载时执行清理,并处理订阅在卸载后才返回的情况。

disconnect(): void 结束整个客户端连接,拒绝未完成请求并清理订阅。页面重新加载会自动处理这些工作。已断开的客户端不能复活;需要独立重连时创建新客户端。不要在每个组件卸载时断开共享的 trove 单例。

结构化错误#

ts
import { trove, TroveError } from "@trove/plugin-sdk";

try {
  await trove.call("host.runtime", "getHostInfo", {});
} catch (error) {
  if (error instanceof TroveError) {
    console.error({
      code: error.code,
      message: error.message,
      retryable: error.retryable,
      traceId: error.traceId,
    });
  } else {
    console.error(error);
  }
}

TroveError 继承 Error,包含 codemessage、可选 data、默认 false 的 retryable,以及可选 traceId。根据 code 而不是翻译后的消息文本判断错误类型。为用户显示有意义的提示,并保留 trace ID 供调试。常见错误及恢复步骤见问题排查

自定义客户端与测试#

createTroveClient({ bridge?, context?, onListenerError? }) 创建独立客户端。onListenerError 接收事件监听器抛出的异常。TroveBridge 实现 protocolVersion: 1connect(listener)send(message)disconnect()

浏览器测试使用 createMockBridge(handlers) 和显式客户端。处理函数的键为 "service.method",Mock 不会自动替代生产通讯层。完整示例见测试指南