III Browser SDK 完整指南:在浏览器中注册函数、触发调用与实时流式通信
III Browser SDK 完整指南在浏览器中注册函数、触发调用与实时流式通信【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii本文是 iii 项目 Browser SDK API 参考文档 的深度展开版。III Browser SDKnpm 包名iii-browser-sdk让前端页面作为一个 III Worker 直接接入 III 引擎通过一条原生浏览器 WebSocket 长连接完成函数注册、函数触发同步 / 异步 / 队列、自定义触发器类型、State 状态管理与 Stream 流式订阅。读完本文你将掌握如何在浏览器中初始化 SDK、注册可被后端反向调用的函数、用TriggerAction控制调用路由、用iii-browser-sdk/state与iii-browser-sdk/stream子路径操作共享状态与实时数据以及如何利用连接状态监听与重连配置构建健壮的实时前端。为什么需要浏览器端 SDK从仓库内 iii-browser-sdk README 可以看到Browser SDK 的设计目标是把前端变成一个 III Worker它带来四个核心能力持久连接一条 WebSocket 取代大量 HTTP 往返避免轮询双向通信引擎可以调用注册在浏览器里的函数后端 Worker 通过trigger()把数据实时推送到前端同构 APIregisterFunction、trigger、registerTrigger等原语与服务端 SDK 完全一致零 Node.js 依赖运行在任何具备原生WebSocket的浏览器环境不带 OpenTelemetry 依赖见 package.json 的description字段no OpenTelemetry, no Node.js dependencies。从源码结构看SDK 主体位于 sdk/packages/node/iii-browser/src由iii.ts核心ISdk实现、channels.ts、state.ts、stream.ts、triggers.ts、iii-constants.ts、iii-types.ts、types.ts等模块组成。本文对应的 API 参考文档 docs/reference/sdk-browser.mdx.skill.md 是由 docs/next/scripts/generate-api-docs.mts 依据这些源码中的 doc-comment 自动生成的。安装npm install iii-browser-sdk包提供 ESM / CJS 双格式产物并内置了多个子路径导出exports字段定义在 package.json导入路径内容iii-browser-sdk核心 APIregisterWorker、ISdk、TriggerAction、MessageType、各类注册输入与句柄类型iii-browser-sdk/state状态管理IState、StateGetInput、StateSetInput、StateUpdateInput等iii-browser-sdk/stream流式数据IStream、StreamTriggerConfig、UpdateOp系列原子操作iii-browser-sdk/helpers辅助函数createChannel、createStream见 helpers.ts初始化registerWorkerimport { registerWorker } from iii-browser-sdk const worker registerWorker(ws://localhost:49135)签名registerWorker(address: string, options?: InitOptions) ISdkaddress是 III 引擎的 WebSocket 地址如ws://localhost:49135。SDK 构造时会自动建立 WebSocket 连接源码见 iii.ts 构造函数中的this.connect()无需手动拨号。InitOptions 完整字段字段类型默认值说明workerNamestringbrowser:随机后缀向引擎宣告的 Worker 名称。浏览器没有 pid 可区分且引擎在每个命名空间内只允许一个同名的存活 Worker因此 SDK 默认按客户端生成唯一名称避免两个标签页共用固定名称时互相驱逐见 iii.ts 与randomId()实现 iii.tsnamespacestring引擎default命名空间Worker 注册与函数、触发器注册所在的命名空间。注意浏览器没有process.env因此没有环境变量兜底必须显式传参传入空字符串会被拒绝见 iii.tsinvocationTimeoutMsnumber30000worker.trigger()调用的默认超时毫秒reconnectionConfigPartialIIIReconnectionConfig见下表WebSocket 断线重连行为headersRecordstring, string忽略浏览器 WebSocket 通过查询参数或 Cookie 鉴权headers选项会被忽略重连配置 IIIReconnectionConfig重连采用指数退避 抖动策略默认配置常量定义在 iii-constants.ts字段默认值说明initialDelayMs1000起始延迟毫秒maxDelayMs30000最大延迟上限毫秒backoffMultiplier2指数退避倍数jitterFactor0.3随机抖动因子0–1用于打散并发重连maxRetries-1最大重试次数-1表示无限重试典型用法const worker registerWorker(ws://localhost:49135, { invocationTimeoutMs: 10000, reconnectionConfig: { maxRetries: 5, initialDelayMs: 500 }, })连接状态 IIIConnectionStatetype IIIConnectionState disconnected | connecting | connected | reconnecting | failed状态机在 iii-constants.ts 定义。测试用例tests/connection.test.ts验证了以下关键行为订阅监听器会立即以当前状态触发一次之后每次状态迁移都会触发支持多个监听器同时订阅存在致命错误如WORKER_NAMESPACE_CONFLICT工作器名称冲突最终状态为failed不再重连且挂起的调用会被拒绝非致命错误如FUNCTION_NAMESPACE_CONFLICT连接保持connected不影响后续使用。核心方法registerTrigger注册触发器将触发器绑定到已注册的函数事件发生时引擎调用目标函数。签名registerTrigger(trigger: RegisterTriggerInput) TriggerRegisterTriggerInput字段字段类型必填说明typestring是使用的已注册触发器类型标识如storage::object-created、http、cronfunction_idstring是触发器触发时调用的函数 IDconfigunknown是触发器类型专属配置需匹配该类型期望的结构示例const trigger worker.registerTrigger({ type: cron, function_id: my-service::process-batch, config: { expression: 0 */5 * * * * * }, }) // 之后移除触发器 trigger.unregister()实现细节iii.tsSDK 会在注册时用randomUUID()生成触发器实例 ID并把触发器的命名空间默认解析为当前 Worker 的命名空间而不是引擎的default从而保证触发器 → 函数在同一个命名空间内解析成功。registerFunction注册浏览器本地函数注册一个在浏览器会话本地执行的异步处理器。注意HTTP invocation 配置是 Node.js SDK 的特性浏览器 SDK 不接受该配置。签名registerFunction(functionId: string, handler: RemoteFunctionHandler, options?: RegisterFunctionOptions) FunctionRefRemoteFunctionHandler类型type RemoteFunctionHandler (data: TInput) PromiseTOutputRegisterFunctionOptions可选字段description函数描述、metadata任意元数据、request_format/response_formatRegisterFunctionFormat描述请求/响应结构。示例// 本地处理器 const ref worker.registerFunction( greet, async (data: { name: string }) ({ message: Hello, ${data.name}! }), { description: Returns a greeting }, ) // 之后移除函数 ref.unregister()返回的FunctionRef包含id函数唯一标识和unregister()从引擎移除该函数。源码中的校验逻辑iii.ts空函数 ID 抛错、重复注册抛错函数处理器会被包装进内部Map等待引擎的InvokeFunction消息回调。典型实时场景——后端推送数据到前端无需轮询iii.registerFunction(ui::update-dashboard, async (metrics: { cpu: number; memory: number; requests: number }) { document.getElementById(cpu)!.textContent ${metrics.cpu}% document.getElementById(memory)!.textContent ${metrics.memory}MB return null })trigger触发函数调用通过请求对象调用函数路由行为由action字段决定。签名trigger(request: TriggerRequestTInput) PromiseTOutputTriggerRequest字段字段类型必填说明function_idstring是要调用的函数 IDpayloadTInput是传给函数的输入数据actionTriggerAction否路由方式省略则同步请求/响应timeoutMsnumber否覆盖默认调用超时毫秒TriggerAction工厂对象iii.ts 中的路由分支工厂方法行为返回类型省略action同步等待函数返回PromiseTOutputTriggerAction.Enqueue({ queue })经命名队列异步处理引擎入队后先确认PromiseEnqueueResult含messageReceiptIdTriggerAction.Void()即发即忘不等待响应Promiseundefined示例// 同步调用 const result await worker.trigger{ name: string }, { message: string }({ function_id: greet, payload: { name: World }, timeoutMs: 5000, }) console.log(result.message) // Hello, World! // 即发即忘 await worker.trigger({ function_id: send-email, payload: { to: userexample.com }, action: TriggerAction.Void(), }) // 入队异步处理队列必须在队列 Worker 的 queue_configs 中声明 const receipt await worker.trigger({ function_id: process-order, payload: { orderId: 123 }, action: TriggerAction.Enqueue({ queue: orders }), })实现要点同步调用会生成invocation_id将 resolve/reject 挂入内部invocations表并设置setTimeout超时默认 30000ms超时后拒绝并移除挂起项Void()路由直接发送InvokeFunction消息并立即返回undefined。引擎内置函数engine::前缀会被路由到default命名空间避免泄漏到 Worker 命名空间见invocationNamespace实现 iii.ts。registerTriggerType注册自定义触发器类型触发器类型定义了外部事件HTTP、cron、queue 等如何映射为函数调用。签名registerTriggerType(triggerType: RegisterTriggerTypeInput, handler: TriggerHandlerTConfig) TriggerTypeRefTConfigRegisterTriggerTypeInput字段id类型唯一标识如state、durable:subscriber、description人类可读描述。TriggerHandler字段字段类型必填说明registerTrigger(config: TriggerConfigTConfig) Promisevoid是触发器实例注册时被调用unregisterTrigger(config: TriggerConfigTConfig) Promisevoid是触发器实例注销时被调用示例——自定义 cron 触发器类型type CronConfig { expression: string } worker.registerTriggerTypeCronConfig( { id: cron, description: Fires on a cron schedule }, { async registerTrigger({ id, function_id, config }) { startCronJob(id, config.expression, () worker.trigger({ function_id, payload: {} }), ) }, async unregisterTrigger({ id }) { stopCronJob(id) }, }, )返回的TriggerTypeRefTConfig是一个带类型约束的句柄提供便捷方法调用方无需重复填写type字段方法说明id触发器类型标识registerTrigger(functionId, config)注册绑定到该触发器类型的触发器自动把命名空间对齐到 Worker 的命名空间registerFunction(functionId, handler, config)注册函数并立即绑定到该触发器类型unregister()从引擎注销该触发器类型unregisterTriggerType注销触发器类型unregisterTriggerType(triggerType: RegisterTriggerTypeInput) voidworker.unregisterTriggerType({ id: cron, description: Fires on a cron schedule })addConnectionStateListener监听连接状态订阅连接状态迁移处理器会立即以当前状态触发一次之后每次迁移触发支持多个监听器返回取消订阅函数。签名addConnectionStateListener(handler: (state: IIIConnectionState) void) () void示例const unsub worker.addConnectionStateListener((state) { console.log(connection state:, state) }) // 之后停止接收更新 unsub()shutdown优雅关闭shutdown() Promisevoidawait worker.shutdown()实现iii.ts置位关闭标志、清除重连定时器、拒绝所有挂起调用错误为 iii is shutting down并清理资源。状态管理iii-browser-sdk/stateIState接口提供基于scope命名空间 key的状态操作通过iii-browser-sdk/state子路径导出类型定义见 state.ts方法签名说明get(input: StateGetInput) PromiseTData \| null按 scope 与 key 取值set(input: StateSetInput) PromiseStateSetResultTData \| null创建或覆盖状态值delete(input: StateDeleteInput) PromiseDeleteResult删除状态值list(input: StateListInput) PromiseTData[]列出 scope 内全部值update(input: StateUpdateInput) PromiseStateUpdateResultTData \| null对状态值应用原子更新操作输入输出类型要点StateGetInput/StateDeleteInput{ scope, key }StateSetInput{ scope, key, value }StateSetResult返回new_value新值与old_value旧值若存在StateUpdateInput{ scope, key, ops }ops是有序的原子更新操作列表UpdateOp[]StateUpdateResultnew_value/old_value之外还有可选的errors: UpdateOpError[]目前仅merge操作在输入违反校验边界时产出。原子更新操作 UpdateOptype UpdateOp UpdateSet | UpdateIncrement | UpdateDecrement | UpdateAppend | UpdateRemove | UpdateMerge操作字段语义UpdateSetpath,value将指定路径字段设为值空字符串 path 指向根值UpdateIncrementpath,by数值字段增加指定量UpdateDecrementpath,by数值字段减少指定量UpdateAppendpath?,value向数组追加元素 / 拼接字符串 / 在嵌套路径推入新值UpdateRemovepath移除指定路径字段UpdateMergepath?,value将对象浅合并进目标根或嵌套位置MergePath类型type MergePath string | string[]省略path、传或[]均指向根值传字符串表示第一层字段传字符串数组表示嵌套路径每个元素是字面量键点号不解释为分隔符[a.b]指向名为a.b的单个键而非a → b。UpdateOpError提供稳定的错误信息结构code如merge.path.too_deep、message、op_index出错操作在ops数组中的下标、可选doc_url。更新校验边界UpdateMerge与UpdateAppend的引擎侧校验见 sdk-browser.mdx.skill.md 的UpdateMerge/UpdateAppend条目路径深度 32、路径段 256 字节、值深度 16、顶层键 1024 会被结构化错误拒绝任何__proto__/constructor/prototype路径段或顶层键会被拒绝防原型污染append语义嵌套路径上缺失/为 null 的中间层自动创建缺失叶子总是创建为数组已存在的对象/标量叶子返回append.type_mismatch结果中的errors数组仅在出错时出现无错时字段省略。流式数据iii-browser-sdk/streamIStreamTData接口用于自定义流实现可覆盖引擎对某个流名的内置存储通过helpers中的createStream传入见 helpers.ts。方法包括get/set/delete/list/listGroups对应输入类型StreamGetInput、StreamSetInput、StreamDeleteInput、StreamListInput、StreamListGroupsInput均以stream_namegroup_iditem_id寻址。流触发器配置stream触发器——监听流条目变更字段类型必填说明stream_namestring是要监听的流名仅该流的变更触发处理器group_idstring否设置后仅该组内变更触发item_idstring否设置后仅该条目变更触发condition_function_idstring否条件执行函数 ID返回false时跳过处理器处理器输入StreamChangeEventstreamName、groupId、id?、timestamp、type: stream以及事件详情event: { data, type: create | update | delete }。stream:join/stream:leave触发器——监听订阅加入/离开StreamJoinLeaveTriggerConfig仅含可选condition_function_id事件负载StreamJoinLeaveEvent含stream_name、group_id、id?、subscription_id、可选context来自StreamAuthResult。流认证StreamAuthInputaddr、headers、path、query_params→StreamAuthResult可选context认证后传给流处理器。StreamContext即StreamAuthResult[context]的提取类型。流式通道ChannelChannel是用于Worker 与 Worker 之间数据传输的流式通道对通过iii-browser-sdk/helpers的createChannel辅助函数创建实现见 iii.tsSDK 会调用引擎内置函数engine::channels::create返回 writer/reader 两个端点及其可序列化引用。import { createChannel } from iii-browser-sdk/helpers const { writer, reader, writerRef, readerRef } await createChannel(worker)字段类型说明writer/readerChannelWriter/ChannelReader通道写端 / 读端使用原生浏览器 WebSocketwriterRef/readerRefStreamChannelRef可序列化端点引用可放进调用 payload 传给其他 WorkerStreamChannelRef字段channel_id通道唯一标识、access_key认证访问密钥、directionread | write标识读端或写端。RBAC 鉴权集成Browser SDK 的类型体系完整覆盖 RBAC 代理 Worker 的接入契约AuthInputWebSocket 升级时传给 RBAC 鉴权函数的输入包含升级请求的headers、query_params每个键映射为数组以支持重复键、ip_addressAuthResult鉴权函数返回值控制 Worker 可调用的函数与上下文字段与默认值字段默认值说明allow_function_registrationtrue是否允许注册新函数allow_trigger_type_registrationfalse是否允许注册新触发器类型allowed_functions[]expose_functions之外额外允许的函数 IDforbidden_functions[]即使匹配expose_functions也拒绝的函数 ID优先级高于 allowedallowed_trigger_types全部允许允许注册触发器的类型 IDfunction_registration_prefix无应用于该 Worker 注册的所有函数 ID 的前缀context{}每次调用转发给中间件函数的任意上下文MiddlewareFunctionInput每次经 RBAC 端口的调用都会传给中间件函数可检查、修改或拒绝调用包含function_id、payload、context、可选action注册钩子OnFunctionRegistrationInput/Result、OnTriggerRegistrationInput/Result、OnTriggerTypeRegistrationInput/Result分别对应函数注册、触发器注册、触发器类型注册的映射/拒绝钩子——返回可能被映射后的字段或抛异常拒绝注册结果中省略的字段保持注册请求的原始值。引擎常量与消息类型EngineFunctionsiii-constants.ts引擎内置函数路径如engine::workers::register、engine::functions::list、engine::functions::info、engine::workers::list/info、engine::triggers::list/info、engine::registered-triggers::list/info。命名注意点LIST_TRIGGERS/INFO_TRIGGERS指触发器类型模板LIST_REGISTERED_TRIGGERS/INFO_REGISTERED_TRIGGERS指触发器实例订阅行旧的engine::trigger-types::list内置函数已移除由engine::triggers::list承接EngineTriggersengine::functions-available引擎触发器类型MessageTypewire 判别器invokefunction、invocationresult、registerfunction、registertrigger、registertriggertype、triggerregistrationresult、unregisterfunction、unregistertrigger、unregistertriggertype、workerregistered。命名空间语义浏览器特性与 Node / Python / Go SDK 不同浏览器没有环境变量可用因此命名空间只能通过InitOptions.namespace与各调用参数显式传递iii.ts省略namespace→ 继承 Worker 的命名空间Worker 未指定时落入引擎default显式传入空字符串会被拒绝namespace is empty错误——未设置与设置为空含义相反??会转发空串因此 SDK 选择直接抛错避免歧义对engine::前缀的内置函数调用默认路由到default命名空间防止引擎内置函数泄漏进 Worker 命名空间。相关测试tests/connection.test.ts验证了配置了命名空间时 register-worker 宣告载荷包含 namespace、未配置时省略、以及按调用序列化 per-call namespace 到InvokeFunction消息。工程验证与测试SDK 自带完善的测试体系sdk/packages/node/iii-browser/tests单元测试connection.test.ts连接状态机、致命/非致命命名空间冲突、重连行为、triggers.test.ts、trigger-types.test.ts、channels.test.ts、helpers.test.ts、exports.test.ts子路径导出完整性集成测试tests/integrationtriggers.test.ts、trigger-type-lifecycle.test.ts、functions-available-trigger.test.ts、channels.test.ts等通过vitest.integration.config.ts运行验证 SDK 与真实引擎的端到端交互类型级测试trigger-typing.type-check.ts、middleware-input-namespace.type-check.ts在编译期校验泛型推导与 RBAC 中间件输入结构。若需要修改 API 文档文案或格式应编辑源码 doc-commentsdk/packages/node/iii-browser/src 下的 prose或 docs/next/scripts 中的生成脚本再重新生成本文对应的参考文档而不是直接编辑自动生成的 docs/reference/sdk-browser.mdx.skill.md。小结III Browser SDK 用一条 WebSocket 连接统一了前端的函数注册、调用、触发、状态与流式通信registerWorker负责连接与重连registerFunction让浏览器函数可被后端反向调用trigger配合TriggerAction实现同步 / 即发即忘 / 队列三种路由registerTriggerType支持自定义事件映射iii-browser-sdk/state与iii-browser-sdk/stream提供带原子更新和严格校验的共享数据能力RBAC 类型体系则保证了多租户与安全接入。配合连接状态监听与命名空间语义你可以构建出实时、可观测、健壮的前端 Worker 应用。【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考