From ce6b3e67496277b2f196df4010a817d2fff95cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E7=82=8E?= <635735027@qq.com> Date: Mon, 13 Apr 2026 16:06:41 +0800 Subject: [PATCH] docs: add async browser script support design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Design for fixing Promise serialization issue in build_eval_js. Async functions return Promise which gets JSON.stringify'd to "{}". 🤖 Generated with [Qoder][https://qoder.com] --- ...-13-async-browser-script-support-design.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-13-async-browser-script-support-design.md diff --git a/docs/superpowers/specs/2026-04-13-async-browser-script-support-design.md b/docs/superpowers/specs/2026-04-13-async-browser-script-support-design.md new file mode 100644 index 0000000..a9f0975 --- /dev/null +++ b/docs/superpowers/specs/2026-04-13-async-browser-script-support-design.md @@ -0,0 +1,69 @@ +# 异步 Browser Script 支持设计 + +## 问题 + +`collect_lineloss.js` 的 `buildBrowserEntrypointResult` 是 async 函数,但 `build_eval_js` 生成的执行代码是同步的,导致 Promise 被 JSON.stringify 序列化为 `{}`。 + +**日志表现**: +``` +[execute_browser_script_impl] 返回成功, payload 长度: 4 +``` +返回 `{}(4字符)` 而不是实际的报表数据。 + +## 根本原因 + +`callback_backend.rs` 的 `build_eval_js` 函数: +```javascript +var v=(function(){return {script}})(); // 同步执行 +var t=(typeof v==='string')?v:JSON.stringify(v); // Promise -> "{}" +``` + +当 script 返回 Promise 时,`JSON.stringify(Promise)` 返回 `{}`。 + +## 解决方案 + +修改 `build_eval_js` 支持 Promise: + +1. 用 `await` 等待 script 执行结果 +2. 检测结果是否为 Promise,如果是则等待 resolve +3. 保持对同步脚本的向后兼容 + +## 实现细节 + +修改 `src/browser/callback_backend.rs` 的 `build_eval_js` 函数: + +```javascript +(async function(){ + try { + var v = await (function(){return {script}})(); + // 等待 Promise resolve + if (v && typeof v.then === 'function') { + v = await v; + } + var t = (typeof v === 'string') ? v : JSON.stringify(v); + // ... 回调逻辑保持不变 + } catch(e) {} +})() +``` + +关键点: +- 包装整个 IIFE 为 async +- 用 `await` 等待 script 执行 +- 检测 Promise-like 对象 (`v.then === 'function'`) +- 向后兼容:同步脚本直接返回值,async 脚本返回 Promise 后被 await + +## 影响范围 + +- `src/browser/callback_backend.rs`: 修改 `build_eval_js` 函数 +- 所有 `browser_script` 类型的 skill 自动支持 async + +## 测试验证 + +1. 运行 `cargo test` 确保现有测试通过 +2. 端到端测试 `tq-lineloss-report.collect_lineloss` 返回实际数据而非 `{}` +3. 验证同步脚本(如知乎热榜)仍然正常工作 + +## 不在范围内 + +- 不修改 `wrap_browser_script`(方案 C 的做法) +- 不修改 skill 脚本本身