@forge-go/client-devtools

中文文档
1.13.7发布于 2026/11/12MITTypeScriptES Module零依赖近 30 天下载 2090

Forge 客户端运行时间的 Dev- 仅检查器: 缓存和标记图检查, 边框的因果事件日志, 以及为什么查询有或没有调试的答案

中文使用文档
文档目录16 节
  1. 回答的问题
  2. 为何这个查询不调试 ?
  3. 为什么这个查询要调试 ?
  4. 缓存里有什么 Order:7 在哪个版本?
  5. 哪些询问取决于这个实体?
  6. 哪些套接字是开着的,哪些频道,哪些参考文献算数?
  7. 而且,没有运行任何东西
  8. 检查不突变
  9. 日志被绑定
  10. 框架抓取, 选择使用
  11. 通过身份改变
  12. 零生产成本
  13. 预算
  14. 重叠
  15. 小组
  16. 核心内容

@ forge-go/ 客户端演示工具

为什么缓存会做它做的.

带有标签图的正态缓存具有特性失败模式,它就是 不是"没用" 没错 它做了一些出乎意料的事 没有杠杆 找出为什么 ——"停机坪中继"和"阿波罗"被取名. 令人惊讶的是 很少发生空难 查询应避免,或更糟,因为 静悄悄的,一个没有反弹,应该有, 屏幕静悄悄地 错误的,只要会话持续.

整个理由 声明 标记而不是猜测依赖性 即该图可检查。 这个包裹就是用来兑现的.

if (process.env.NODE_ENV !== 'production') {
  void import('@forge-go/client-devtools').then((devtools) => {
    globalThis.forge = devtools.attach(client);
  });
}

这样一来,一个生产建筑 既不包含这个包,也不包含 本来会装上它的分行. 见 零生产成本 见下文.

回答的问题

为何这个查询不调试 ?

那个很重要的 丢失的无效性产生无事件、无错误和无 请求.

forge.whyNotRefetched('GET /orders');
outcome:     missed
reason:      `GET /orders` did not refetch because none of the 1 tag(s)
             mutation POST /orders raised are tags it carries. The two sets are
             disjoint.
invalidated: Order:9
carried:     Customer:c1, Order:1, Order:2, Order[]
matched:     (none)
nearest:     Order:9 vs Order[]  (instance-vs-collection)
suggestion:  the mutation invalidated the instance `Order:9` but this query
             provides the collection `Order[]`, and the two never intersect. A
             query only carries `Order:9` once a response has actually put that
             entity in its result — which a create never has. Add `Order[]` to
             the operation's Invalidates.

5个结果,因为它们是5个不同的bug 并且将其中任意两个集合起来 他们需要一个下午:

结果这是什么意思
missed标签集是脱节的。 声明是错误的; 已读 nearest。 。 。 .
stale-while-unmounted它们相互交织,但没有任何查询程序,所以没有提出任何请求. 正确的行为,以及最常见的关于破损缓存的虚假报告。 它在下个山上反弹.
placed接了回话 如果屏幕错误,则回调错误.
refetched它确实反射了。 问题在于缓存的下游.
not-tracked此密钥不是缓存的 。 一个关键包括它的论点.

nearest 名称 : instance-vs-collection, (中文(简体) ), collection-vs-instance, (中文(简体) ), different-instance, (中文(简体) ), case, (中文(简体) ), scoped ——每个都有宣言要改变.

第六个原因单独报告,因为它是建筑所看不见的:a 标签模板 毫无结果地被跳过。 。 。 . Order:{res.id} 反对无答复 id 完全无效,什么都不说. cause.unresolved 是那里出现了.

为什么这个查询要调试 ?

forge.whyRefetched('GET /orders');
// `GET /orders` refetched because mutation PATCH /orders/{id} invalidated
// Order:1, Order[], of which it carries Order:1, Order[].

reason 实值 invalidation, (中文(简体) ), mount 或者说 manual;原因是突变或 从日志中找到的.

不知道你问的是什么问题? forge.explain(key) 选择.

缓存里有什么 Order:7在哪个版本?

forge.entity('Order:7');
// { key, type, id, version, frameAt, fields, refs, dependents }

version 只有在数据实际移动时才会发生突起,所以反射功能已经改变 无所不离. frameAt 当一个流框写它时是非零. refs 是此记录点所在的实体; 引用出现在 fields 作为 {__ref: 'Customer:c1'},这是缓存真正持有.

哪些询问取决于这个实体?

forge.dependents('Customer:c1'),或 dependents 领域 entity这个 通过嵌入式引用到达: 命令渲染列表 order.customer.name 取决于 Customer:c1 从来没有宣布它.

哪些套接字是开着的,哪些频道,哪些参考文献算数?

forge.sockets();
// [{ endpoint: '/ws/orders', connected: true, refs: 2, opens: 1,
//    reconnecting: false, channels: [{ channel: '/ws/orders', handlers: 2 }] }]

同一实时查询的10个组件是一个套接字. opens > 1 意思是说 扔了下来,又回来了——一个重新连接意味着没有看到帧.

而且,没有运行任何东西

forge.wouldInvalidate(ops.orderCreate, { body: {} }, { id: 9 });
// { tags: ['Order:9'], unresolved: [], missed: ['Order:9'], hits: [...] }

missed 是没有挂载查询的标签 。 问突变会做什么 无法通过操作来解答, 因此通过同样的程序解决模板 resolveTags 无效文件使用并读取标签索引——没有请求,没有 写作.

检查不突变

没有任何功能 读取 侧调 getState, (中文(简体) ), fetch, (中文(简体) ), read 或者说 denormalize这比听起来要不明显. cache.getState(meta, args) - 自然的 - 自然的 - 自然的 - the natural 读取查询的方式——电话 open,哪个 将记录移动到后面 LRU 订单 并创造一个,如果它不见了, 然后补水骨架, 构建存储备忘录,将其链接到逆向依赖索引和写入中 登记条目中的结果 value一个巡视员会利用它 更改下一个被删除的查询, 更改发送的回调位置 作为 current,并填入无人问询的备忘——仅此而已 有人打开了面板 这是最糟糕的失败模式 调试工具 .

整个读取的表面是地图查看和计数器,每个快照都是 复制: 写给 snapshot.fields 无法移动商店。 测试 套房声称记录计数、记录版本、私人LRU订单和完整 登记国(包括 value 按身份划分)通过之后保持不变 包括显示这些说法的探测器 失败当 getState 改为使用.

有一半是变异的 它是一个文件. forge.actions 反弹, 无效、驱逐、丢弃和清除,这是带有按钮的面板 需要帮助。 它住在这里 actions.ts 并且没有其他的地方,所以上面的段落留下 字面上真实的 inspect.ts 而不是包的大致真实, 因此可以移动这个缓存的整组电话都适合在一个屏幕上. 每一个记录它做了什么, 所以一个行动是相同的 log,与它引发的事件顺序相同.

日志被绑定

一个固定大小的环,默认有500个条目,分配一次,从未增长. 何时 它填满,最古老的条目是覆盖和 dropped 数到多少 所以一个从中层故事开始的时间线就这么说了.

这是什么 内 条目也受了约束,这是容易错过的一半. 没有任何保留能够保留一页数据:没有反应体,没有 错误对象, 无还水值 。 事件解决并复制标记 到达时, 参数被压缩为切换到缓存密钥, 错误变为 短字符串。 每平时的记账是针对缓存的LRU的 上限而不是每个查询密钥增加一个条目 .

框架抓取, 选择使用

这里的每个其它条目都以构造为界: 标记是复制字符串, 参数是短写缓存键,错误是消息。 一个流框 载荷不是其中之一,所以捕捉一个是 唯一保留的地方 规则被打破, 你必须要求它.

attach(client, { frames: { limit: 200 } })

默认关闭; frames: {} 开到200分 存在是开关,不是 号码。 打开了, forge.frames() 给您最后一个 N 解码框架 他们的渠道,信息,意图和身体, 这是你想要的,当一个 框架到达,屏幕不变。 捕获时复制有效载荷 并盖上深度和宽度, 所以任何戒指都无法保存一个商店 记录活着。 仍然需要内存 以你设定的限度为界.

通过身份改变

setPrincipal 丢弃整个缓存, 所以没有记录之前它描述 之后存在的商店。 因此,检查员不假装跨越 边界: 它记录 a principal 条目,递增一个会话计数器 在每个条目中印出其会话。 查询在下方重挂和重挂 新身份被记录为 挂载,而不是作为查询 数据不复存在。 缓存快照只显示当前 校长的数据,因为这是唯一的数据.

零生产成本

约束性约束,并对照 已建产出 相当 而不是来自来源的争论.

核心的接合是一个无效的字段 QueryCache 和五个可选的电话. 如果被调用者无效,可选择调用不评估其论据,所以 没有随行的检查员甚至没有分配——一个财产负荷 一张无效支票. 核心没有历史: 每起事件都被移交 或被遗忘, 和环缓冲, 因果关系和分析 所有 住在这里.

__tests__/zero-cost.test.ts 编译软件包 tsc组合 3 与真正的建筑完全一样的固定应用程序将并读取 字节 :

固定图击出
使用运行时间, 绝不导入 devtools9325 B类
为生产而建造9313 B类
静态导入devtools14573 B (韩语)
静态导入编组和面板页:1

生产捆绑没有包含此包的标记字符串 乐器之一 包含所有, 这使得没有 有意义的。 被保护的包裹里没有 import( 树枝折叠 而块子从未被射出.

有一件事实验确定了困难的方法: 将警卫写成一个 赤线 process.env.NODE_ENV !== 'production'以防御方式拼写为 typeof process === 'undefined' || process?.env?.NODE_ENV !== 'production',则 下半部分仍然折叠,但第一个部分无法,断开部分存活下来 整个包裹船.

预算

条目击出预算
检查 API5675 B (韩语)6千贝
覆盖2788 B (英语)3.5千贝
面板4594号B12千贝
巡视员和重叠在一起8495个B级9千贝

设计给予这个软件包没有预算,因为它没有终端用户可以保护: 它从来没有达到生产捆绑。 上面的数字是用来捕捉的 意外情况 bloat——为一张桌子绘制图表的图书馆——被设定为 巡视员不能悄悄地度过巡视时间.

inspection API 当时是5.5克B,现在是6克B。 增长的特点是: 动作层、 选入框环、 已读查询细节和批量记录 读取,730B之间。 预算之所以提出,是因为一个只有非宗教的一揽子计划已经获得 能力是一种预算,它的工作。 一个因为.. 生产 组合不会是字节,下表中的两个核心预算 没有被触动.

inspector and overlay together 从同为8.5 kB 移动到9 kB 变化和同样的原因。 这是上面的两个文件总结, 所以它增长 由它们生长而来, 它降落在了它的老线下5 B. 五个字节不是 头室,这是一个绊线:下一个博士评论添加到 index.js 摆好 和预算失败的原因 没有人能采取行动 教导人们 提高限制而不读它们,这是预算绝不能有的 教书.

重叠

import { mountOverlay } from '@forge-go/client-devtools/overlay';

const unmount = mountOverlay(forge, { open: true });

这是整个面板:因果追踪,网络视图,上叠, 控制栏杆,细节和动作. /overlay 财务报告和审定财务报表 /panel 为: 在两个名字下执行相同的规定,所以你所达到的不重要 为.

昔有相相转相. /overlay 是六个只读的表格 /panel 这一切,意味着 遵循你的本能给你 包里能力最差的UI没有告诉你一个更好的 一个子路径离开。 如果你上场 /overlay 在1.11之前,它看起来很薄, 这就是为什么, 更新是整个修复.

瘦取景还来相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 这个 实值 /mini数字 :

import { mountMini } from '@forge-go/client-devtools/mini';

const unmount = mountMini(forge);

6个只读的表格和3.5 kB gzipped中的过滤框. 偏爱 /overlay。 。 。 . 字节是第二个UI的全部案例,它们无法幸存 事实上,这个包是纯正的:没有一件能够生产 捆绑,所以你省下来的 是一个开发建筑。 与此同时,精致的视野 飘来飘去,还有.. log 选项卡,其中面板具有因果关系.

阴影根中的 DOM 面板 : document.createElement 没有别的了. 故意 非组件 – 反应面板部队 – 反应 Vue 应用程序,并使用Angular应用程序强制使用 Vue。 这也是 故意比它下面的API更瘦. 一个超级检查API与一个 平面板击倒了反:API是您在控制台上所说的 早上3点,测试结果如何,别人的面板是什么 建从.

小组

import { mountPanel } from '@forge-go/client-devtools/panel';

const unmount = mountPanel(forge, { open: true });

同样的事情 /overlay 以它最初的名字给你 两者都是 完整的面板; /mini 是那个瘦的 这个小组有什么 /mini 没有:

  • 一个细节的窗帘. 单击查询并获取其状态、挂载、挂载 提供、标记和道具,以及作为 <details> 树。 点击一个实体并获取其版本,框钟读取最后一个 写了它,它的字段,它的参考文献 和它收到的查询,每个都与 是否已经安装了任何设备 .
  • 动作栏,这是任何UI中唯一写作的部分. refetch, (中文(简体) ), invalidate 财务报告和审定财务报表 drop 挂起选中的查询, evict 关 选定实体,以及 clear cache 坐在全球酒吧里。 每个 他们通过 devtools.actions按钮 媒体是同一个呼声 和降落在同一日志.
  • 串流标签,这是 binderSnapshot 制成: 装订、活活 查询及其参考数、队列深度和 recovering 徽标 命名连接后空格窗口中的终点。 那个徽章是 有一件事你看不到其他方法 因为一个客户默默地 漏掉的相框看起来完全像一个没有.
  • 框架标签在你开始捕捉之前是空的,是诚实的: 告诉你,打电话 而不是显示什么.

两个入境点都没有进口另一个,因此它们有单独的预算和 也不可能泡到另一个 和上面的一样 尊重: document.createElement 在阴影的根, 没有框架,没有 角或Vue应用程序必须承担.

核心内容

七事所取,皆可选取,所测也. 三角洲反对 core, REST only (9122 B gzipped) 并被从建筑中移除 输出和再测量:

变动费用
QueryCache.observer +4个发射站点+64 B 调试
applyFrames 发射场,装有相框批次+20 B gziped (只有流)
QueryRegistry.all()+8 B 键
QueryCache.tracked()+11 B 击出
QueryCache.drop(key)+66 B 弹出
socketSnapshot(manager)0 B 除非是进口(在进口时+135 B)
binderSnapshot(binder)0 B 除非是进口(在进口时+126 B)

后面两个是自由的功能,而不是方法 树摇. 以上五种不能:一种分类方法在每次进口中着陆 设定将类拉入,这就是为什么它们被计算而不是 挥了手.

现在的核心总数: 9122 B (韩语) 仅以9.2 kB预算为基点,并 11856 B (韩语) 与流对比为14.25 kB. 整个接缝是149B 第一图和第二图164 B.

版本与发布记录

@forge-go/client-devtools 共发布 25 个版本,首次发布于 2026/08/07;过去 12 个月发布了 25 个版本。

版本发布日期距今
1.13.7latest2026/11/123 天前
1.13.62026/11/105 天前
1.13.52026/11/069 天前
1.13.42026/11/069 天前
1.13.32026/11/0610 天前
1.13.22026/10/2818 天前

关于 @forge-go/client-devtools 的常见问题

@forge-go/client-devtools 是什么?

Forge 客户端运行时间的 Dev- 仅检查器: 缓存和标记图检查, 边框的因果事件日志, 以及为什么查询有或没有调试的答案

如何安装 @forge-go/client-devtools?

在项目目录运行 npm install @forge-go/client-devtools,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@forge-go/client-core(^1.13.7)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@forge-go/client-devtools 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@forge-go/client-devtools 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@forge-go/client-devtools 可以商用吗?

@forge-go/client-devtools 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@forge-go/client-devtools 的下载量有多少?

根据 npm 官方下载统计,@forge-go/client-devtools 在 2026/10/16 – 2026/11/14 这 30 天内被下载 2,090 次,日均约 70 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@forge-go/client-devtools 还在维护吗?

最新版本 1.13.7 发布于 2026/11/12(3 天前);至今共发布 25 个版本,其中过去 12 个月发布了 25 个;首次发布于 2026/08/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。