@ frondruntime/ devtools (英语)
Frond devtools枢纽客户端的一半. 一个呼叫将运行时间附加在本地的中枢上,中枢将它的事件流入并可以问它现在的图表是什么样子的——两者都可以由一个编码代理在MCP上读取.
安装
bun add -d @frondruntime/devtools
依赖性,而不是运行时间。 意图的外形是一种只在发展建筑中存在的呼唤——见: 守卫它 见下文.
普通的双条目无害环境管理库: . 用于附件客户端和 ./node 用于文件系统发现,既已运出,可安装任何软件包管理器,也可在节点、Bun、浏览器捆绑或React Industrial上运行。 Bun 要求属于中枢守护进程, 而不是这个半边形 枢纽。 。 。 .
@frondruntime/core 财务报告和审定财务报表 effect 是同龄人。 没有运行时间依赖.
附加
import { attachDevtools } from "@frondruntime/devtools";
const detach = attachDevtools({ runtime, name: "my-app" });
这是普通案件的全部配置表层。 没有 url,它拨打枢纽的默认地址;没有 platform它从环境中猜到一个。 返回的函数解开 .
随心所欲 永不舍弃 如果没有枢机监听,每两秒钟就悄悄地重复一次,所以在枢机开始之前、停止之后和在两边重新开始之前,呼叫是安全的。 过 onError 如果你想知道它为什么不连接.
"永远"有一个例外. 一个枢纽 拒绝 附件——今天,只有协议版本不匹配——正在回答关于这个构件的问题,每一次重试都会再次问,得到相同的答案. 所以,拒绝停止循环, 大声地说,一次,在控制台上。 供应 onError 拥有报告它的所有权 并沉默的回落。 另一种方法是它过去所做的: 默默地每两秒钟重排一次, 用于一个永远不会附加的过程的整个生命周期.
发送什么
事件流,和——当枢纽问起——一张图的正文快照,这就是枢纽的背面 frond_read_state 工具。 两者都经过同样的编码器,所以一个在快照中失败的节点和失败的事件读取相同.
任意一个值默认都会被编辑 . attachDevtools 声明a 上限 和枢机要求一个政策; 两者中得分越小, 天花板默认为 "shape"数字 :
| 政策 | 线上值是什么样子 |
|---|---|
"none" | 字义 "withheld",以取代每个值 |
"shape" | 一行描述符: {id,name,total}, (中文(简体) ), Wired{_tag,run}, (中文(简体) ), string[42], (中文(简体) ), Map(3) |
"full" | 以深度、 字符串长度、 条目数和每笔记录值数为界的值本身 |
attachDevtools({ runtime, name: "my-app", values: "full" });
选择到 "full" 每个应用程序,故意。 值得调试的运行时间是那些持有标志和账户状态的运行时间,而船舶值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值值 中枢总是要求 "full" ——当附件被接受时,为事件流一次,在每个状态上再次读取——所以天花板是唯一站在读者和数据之间的东西. 这是预定的安排,而不是其中的空白:将真实值放入套接字的决定属于拥有它们的应用程序,而不是读取它们的工具.
"none" 是它自己的编码器 而不是更严格的 "shape",因为一个密钥列表本身就是对app数据的描述——一个说它不会发送任何一个的应用程序不应该在图表快照中发送每个节点的密钥名.
每项政策仍然寄送的是如何处理记录的:其标记、记录、记录、记录和记录 nodeIds,并且——在一个信号上——它的频道和事件名称. 这些是过滤器 frond_read_events 并且它们被编为常数 而不是从数据中产生 有效载荷是值,而且 "none" 有效载荷是去.
时 "shape" 描述符是字符串而不是 JSON 对象,因为这个种子是由代理通过 MCP 读取的,并且一个节点结果是四十行的 漂亮打印的 JSON 没有数据比一个更糟糕 {id,name}。数字、布尔字符和字符串最多可达256个字符。在运行时的事件中,这些是ID、标记、时间戳和旗帜,这是整个信号。 任何结构都是描述符,因为节点结果或动作输入总是对象或数组. 一个类案例放弃了它的类型—— AccountModel{?} - 和 _tag 因为一个失败的种子说 {_tag,nodeId} 改为 GraphNodeAcquireFailed 不值得阅读.
每一个约束在 "full" 在输出中宣布自己: {"_": "elided", "by": "depth"} -或者说 "budget",或 "entries" ——行走停止的地方,一个 {"_": "string"} 带有 length 财务报告和审定财务报表 head 弦被剪断的地方。 读者看不见的盖子比低的更糟糕,因为它把"有更多"变成了"所有". 标记将对象保留在一个 _ 在此政策下,它们周围的值是真实数据,而标记必须与一个标记保持区别.
失败
失败不是价值,上面的政策表只适用于其中的一半。 失败是其 原因链首先,因为最外层的链接很少是值得阅读的链接——Frond在解风时包裹故障,a RefreshFailed 围绕 AcquireFailed 绕着你的司机扔的东西 有着自己的空信.
{
"_": "error",
"message": "upstream orders unavailable in eu-west (503)",
"causes": [
{ "index": 0, "tag": "AcquireFailed", "nodeId": "feed:v1:…", "nodeTag": "feed" },
{ "index": 1, "tag": "DriverPromiseFailed", "operation": "acquire" },
{ "index": 2, "name": "Error", "message": "upstream orders unavailable in eu-west (503)" }
]
}
message 它是说出任何事情的最深层的东西——一个被抬起的球场,而不是一个总结。 每个框架都包含故障名称: tag, (中文(简体) ), nodeId, (中文(简体) ), operation, (中文(简体) ), dependency, (中文(简体) ), path。 。 。 .
每个策略都会有信件交叉,包括: "none",理由是一个关闭了价值的应用程序仍然想知道什么是失败的. 有两件事 "full"- 仅: 每一帧 stack,以及 fields - 错误本身的有效载荷 status 财务报告和审定财务报表 endpoint 并请求 id 一个链条不能提前命名.
要完全删除记录而不是编辑记录,过滤:
attachDevtools({
runtime,
name: "my-app",
include: (record) => !record.nodeIds.some((id) => id.startsWith("auth/")),
});
守卫它
if (import.meta.env.DEV) {
attachDevtools({ runtime, name: "my-app" });
}
附加套接字没有经过设计校正——它只携带数据 输入 中心,所以一个不请自来的人 实现的比垃圾在仪表板上更糟糕。 但是,它拨打的枢纽是一个简单的回路端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端端 守护它.
平台
主入口没有进口 node:。运输是全球性的 WebSocket 搭载了ndjson,所以同一个构件从浏览器,从Bun,从Node,以及从React Industrial.
原生反应
没有要安装的内容: 此软件包没有全局用到 WebSocket,所以没有 crypto 要添加的多填充和 Node shim 配置 .
不同之处在于地址. 默认是回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回(回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回.
| 目标 | 怎么办 |
|---|---|
| iOS 模拟器 | 没什么 它分享主机的网络堆栈,所以 ws://127.0.0.1:17391/attach 是中心点. |
| Android 模拟器 | adb reverse tcp:17391 tcp:17391 在主机上,然后默认的 URL 工作不变. |
机器人模拟器,没有 adb | 启动中枢 --host 0.0.0.0 通过 url: "ws://10.0.2.2:17391/attach"。 。 。 . |
| 物理设备 | 启动中枢 --host 0.0.0.0 通过 url: "ws://<host-lan-ip>:17391/attach"。 。 。 . |
adb reverse 更好的是两个Android选项:它将端口通向模拟器以覆盖已存在的调试桥,因此枢纽停留在回转上,而应用则保留了默认的URL. 10.0.2.2 是模拟器对主机的别名,到达它意味着中枢必须在每一个界面上收听.
--host 0.0.0.0 在您的本地网络上设置一个未经认证的套接字 . 中枢对谁在另一端没有任何概念,无论是哪一个方向:任何能到达端口的地方都可以将记录推入一个代理读取的仪表板,并且可以要求所附的应用来获取图快照,直到他们申报的上限。 在一个值得信赖的网络上, 对于一个发展建设来说,这就是贸易; 不要让它这样束缚, 并且根本不用一个其上限是 "full"。 。 。 .
测试
从杰斯特套房接通到Effect的RPC层,它拉入 msgpackr —— Jest 默认的 CJS 变换不能加载的只使用无害环境管理的软件包,而这个软件包没有选择: 这是依赖 effect 因此,这里没有序列化设置可以避免它。 要么作为无害环境管理运行套房,要么让Jest改造:
// jest.config.js
transformIgnorePatterns: ["node_modules/(?!(msgpackr|msgpackr-extract)/)"];
狭义的修补是完全不附着在测试中. attachDevtools 已存在以监视您手动操作的过程; 测试运行没有拨号的枢机, 也没什么可监视的.
文件系统发现是它自己出口的后盾,所以一个浏览器捆绑器从来不需要解决:
import { readHubLock } from "@frondruntime/devtools/node";
const lock = readHubLock(); // undefined when no hub is running
readHubLock 从工作目录上走出来寻找 .frond/hub-<port>.json,运行中枢在退出时写并删除。 用于在中枢倒下时无所作为的脚本.
枢纽
另一个是 @frondruntime/hub一个本地守护进程, 它拥有事件历史, 要求附带的应用程序提供图表快照
bunx @frondruntime/hub
那个守护进程作为TypeScript源头 并用墨水制造,所以它需要 Bun.. npx 无法运行。 没有达到这个包: 附加客户端是构建的无害环境管理,并运行在应用程序的任何地方. 见其 读取。 。 。 .
二分之一必须同意 HUB_PROTOCOL_VERSION 正是,没有能力谈判, 因为部分不匹配 呈现为"运行时间停止排放" 而不是一个错误。 一个看到一个它不识别的版本的中枢拒绝在一行中同时命名数字和哪个侧后方的附件,而这一侧停止了重试并打印.
大赦国际的使用
Frond是AI辅助(主要是Claude和Codex),在数月内被反复使用,而不是一发生成. 全注: https://frondruntime.dev/ai-use (英语)