# bindings.json ## 功能 `bindings.json` 描述扩展对 BT 脚本公开的调用表面。它不写业务逻辑,只声明入口函数、扩展对象、对象方法、参数类型、返回类型和对象生命周期语义。 脚本能调用什么,完全由 `bindings.json` 决定;扩展后端必须提供与 bindings 对应的实现。 ## 语法 ```json { "api_version": 1, "functions": [ { "name": "calc", "id": 1, "params": [ { "name": "value", "type": "int" } ], "returns": "Calc" } ], "objects": [ { "name": "Calc", "type_id": 1, "methods": [ { "name": "add", "id": 2, "params": [ { "name": "value", "type": "int" } ], "returns": "Calc" }, { "name": "value", "id": 3, "params": [], "returns": "int" }, { "name": "close", "id": 4, "params": [], "returns": "bool", "lifecycle": "dispose" } ] } ] } ``` ## 参数 | 字段 | 说明 | | ------ | ------ | | `api_version` | 必须和 `manifest.api_version` 一致,使用 `1`。 | | `functions` | 公开入口函数列表,至少需要一个入口。 | | `functions[].name` | 脚本里看到的全局入口名,例如 `calc`。 | | `functions[].id` | 后端调用 ID,WASM 扩展用它分发到具体 handler。 | | `functions[].params` | 参数列表。 | | `functions[].returns` | 返回类型,可以是原始类型或 `objects` 中声明的对象类型。 | | `objects` | 扩展对象类型列表。 | | `objects[].name` | 对象类型名,必须大写字母开头,例如 `Calc`;脚本中 `type(obj)` 会返回这个名称。 | | `objects[].type_id` | 对象类型 ID,不能为 `0`。 | | `objects[].methods` | 对象方法列表。 | | `methods[].lifecycle` | 方法生命周期,默认 `call`,可写 `dispose`。 | ## 参数类型 bindings 支持以下参数类型: | 类型 | 说明 | | ------ | ------ | | `any` | 任意 BT 值,仅用于参数声明,适合 `bind(value)` 这类需要接收多种基础值的扩展方法。 | | `empty` | BT 的 `empty`。 | | `null` | BT 的 `null`。 | | `bool` | 布尔值。 | | `int` | 整数。 | | `float` | 浮点数。 | | `string` | 字符串。 | | `bytes` | Bytes 二进制字节。 | | `array` | 数组。 | | `object` | 普通对象。 | 返回类型可以使用除 `any` 外的原始类型,也可以使用 `objects` 中已声明的对象类型名。返回类型声明为 `object` 时,扩展可以返回普通对象,也可以返回 `empty` 表示没有对象结果;声明为具体扩展对象类型时仍必须返回对应对象句柄。 ## 返回值 bindings 本身没有运行时返回值。扩展实际返回值由 `returns` 字段约束:如果写原始类型,运行时会校验真实返回值类型;如果写对象类型名,运行时会要求返回对应扩展对象。 当入口或方法返回扩展对象时,脚本可通过 `type()` 读取该对象在 `objects[].name` 中声明的类型名: ```bt num = calc(1) // 输出:Calc print type(num) ``` ## 参数 role 参数默认是普通值: ```json { "name": "value", "type": "int" } ``` 如果参数是给 WASM 扩展使用的路径,可以声明 `role`: ```json { "name": "input", "type": "string", "role": "path_read" } ``` | role | 说明 | | ------ | ------ | | `value` | 普通值,不做路径处理。 | | `path_read` | 读取文件路径,要求 `type` 为 `string`;宿主解析并校验路径,不需要 manifest 权限声明。 | | `path_write` | 写入文件路径,要求 `type` 为 `string`;宿主解析并校验路径,不需要 manifest 权限声明。 | | `path_dir` | 目录路径,要求 `type` 为 `string`;宿主解析并校验路径,不需要 manifest 权限声明。 | ## 代码示例 上面的 bindings 会让脚本获得这样的调用体验: ```bt num = calc(1) num.add(2) value = num.value() // 输出:3 print value ``` ## 注意事项 - 入口名、方法名、参数名必须使用 snake_case,不能以下划线开头或结尾。 - `id` 在同一个 bindings 文件中不能重复,且不能为 `0`。 - 对象 `type_id` 不能为 `0`,同一个扩展内不能重复。 - `lifecycle: "dispose"` 只能用于 `close` 或 `dispose` 方法;方法不能有参数,返回类型必须是原始类型。 - 纯 BT 扩展要求 bindings 中的入口函数和对象方法在 `src/lib.bt` 中存在同名实现。 - `type()` 返回的是脚本可见类型名,不参与扩展方法路由或安全校验;宿主仍使用模块 ID 和类型 ID 管理对象身份。 声明数组返回的查询在不存在结果时可返回 `empty`;显式 `null` 不是数组。同一 shared worker 对象的重复返回复用一个宿主句柄,包括链式方法和任务恢复;close 使其别名全部失效。