@nx-lang/previewer

中文文档
0.10.0发布于 2026/11/02MITTypeScriptES Module构建来源已验证

不稳定的。在@nx-lang/ir-runtime上运行一个NX组件,作为一个无头预览会话:一个带有分支、处理程序调度、场景和热加载的时间轴。没有UI,没有框架。

中文使用文档
文档目录6 节
  1. 会话保存了什么?
  2. 例子
  3. 调度
  4. 热重载
  5. 起源
  6. 选项

@nx-lang / previewer

不稳定的。 API和场景格式可能在任何版本(补丁)中不兼容地更改 释放包括在内。固定一个精确的版本。

运行一个NX组件作为无头预览会话 @nx-lang/ir-runtime。观众回答“这是否说明了我。 意味着吗?”。预览者会回答“它运行正常吗?”:以设计师的身份点击调查 24人一组,退一步,试试“工程师”,保持两条腿。

这个包没有UI,也没有框架。主机绘制会话的当前输出及其时间轴 无论它喜欢什么,在浏览器中,在worker或Node中。

会话保存了什么?

  • 蜱虫。 每次渲染都是一个标记:什么使它(第一个道具,一批,新道具或一个) 重载)、道具、状态、呈现的输出、处理程序返回的效果,以及在哪里 输出的每条记录来自。蜱虫永不改变。
  • 一棵树。 回到扁虱身上没有任何意义。从已经有子代的蜱虫调度 添加另一个子进程,这样两个延续都保留,宿主可以返回到其中一个。
  • 通过指针处理程序。 主机调度到 ActionHandler 记录在输出中找到的, 通过它的JSON指针,会话找到令牌,所以主机永远不会跟踪令牌编号。
  • 场景。 当前路径保存为 program.json 具有名称和每个条目的生命周期 处理程序指针,并在编辑后在同一组件的任何会话中重播。
  • 热重载。 给定一个新程序,当新程序接受它时,会话保持状态, 当路径不存在时重放路径,当道具不再呈现时保留旧程序。

例子

会话需要一个准备好的程序,所以编译是主机的工作。 programFromImages 链接的 图片 @nx-lang/sdk-wasm的 generateNxIr 发出或映像提前构建的主机。

import type { NxHostRecord } from "@nx-lang/ir-runtime";
import { createPreviewSession, programFromImages, replayScenario, type PreviewImage } from "@nx-lang/previewer";

/** Runs the question flow as a designer, tries "engineer" instead, and replays the first run. */
export function previewFlow(images: readonly PreviewImage[]) {
  const program = programFromImages(images, "main.nx");
  const session = createPreviewSession(program, "Flow", { respondent: "friend" });

  // Answer through the handlers the output renders, by where they sit in it.
  const answer = (action: NxHostRecord & { $type: string }) =>
    session.dispatchHandler(`/children/1/on${action.$type.slice("Step.".length)}`, action);
  answer({ $type: "Step.TextAnswered", answer: { $type: "TextAnswer", questionId: "name", value: "Ada" } });
  answer({ $type: "Step.TextAnswered", answer: { $type: "TextAnswer", questionId: "email", value: "[email protected]" } });
  const beforeRole = session.current;
  answer({ $type: "Step.ChoiceAnswered", answer: { $type: "ChoiceAnswer", questionId: "role", selected: "designer" } });
  answer({ $type: "Step.ChoiceAnswered", answer: { $type: "ChoiceAnswer", questionId: "designTool", selected: "canvas" } });
  answer({ $type: "Step.IntegerAnswered", answer: { $type: "IntegerAnswer", questionId: "teamSize", value: 24 } });

  // Save the run before branching: a scenario is the current path, and plain JSON.
  const shared = JSON.stringify(session.scenario("designer, team of 24"));

  // Go back and try another role. Nothing is re-run, and the designer run stays in the tree.
  session.goTo(beforeRole);
  answer({ $type: "Step.ChoiceAnswered", answer: { $type: "ChoiceAnswer", questionId: "role", selected: "engineer" } });
  const branches = session.childrenOf(beforeRole).map((tick) => tick.state.role);

  // Anyone with the same program can replay the saved run.
  const { session: replayed, result } = replayScenario(program, JSON.parse(shared));
  return { branches, completed: result.completed, teamSize: replayed.current.state.teamSize };
}

previewFlow 返回 { branches: ["designer", "engineer"], completed: true, teamSize: 24 } 用于 问题流一致性程序 specs/ir-conformance/question-flow.

调度

  • dispatch(batch) 像运行时一样接受批处理: ActionHandlerInvocation 条目的命名 令牌,或组件发出的动作。条目也可以是 { handler, action },处理者的 JSON指针及其操作。
  • dispatchHandler(pointer, action) 通过指针调度一个操作。行动的 $type 必须 处理程序记录的动作名称。
  • setProps(props) 用新道具渲染当前状态。

它们中的每一个都添加了当前标记的子标记,并使其成为当前标记。调用失败将抛出 NxIrRuntimeError 不加勾号。它的诊断是运行时的(nx-ir-*),或 会话的:

  • nx-preview-handler:一个条目在当前输出中没有处理程序名称,另一个的处理程序名称 操作,或者输出不包含的令牌;
  • nx-preview-batch批不是列表;
  • nx-preview-scenario:一个场景是畸形的,或者是针对另一个组件、模块或路径的 随着道具的改变被导出;
  • nx-preview-tick: tick不是会话保留的;
  • nx-preview-options: maxTicks 不是正整数;
  • nx-preview-program: programFromImages 一个身份有两个图像,还是一个都没有 的条目。

setProps 并且从开始重新加载渲染,因此运行时对新输出的令牌进行编号 (重新h1-1,……)。仅从当前tick中读取令牌,或通过指针调度,这不需要 一点也不值得。

热重载

reload(program) 返回它所做的:

  • kept:新程序接受当前的道具和状态,输出被重新渲染为 重载选项,当前选项的子选项。
  • replayed:状态不再适合,所以当前路径在新程序下再次运行,从a 新根。 completed 和 stopped 说说它走了多远。
  • failed:道具不再渲染,或者渲染达到了会话的限制之一。这个 会话保留旧程序和当前tick。

重载本身不会丢失它开始时的路径 maxTicks 说。在这之后, maxTicks 和平常一样。旧路径脱离当前路径,并且会话下降一个刻度 只有当它没有子节点时,所以一旦会话超过了限制,以后的调用就会放弃旧的路径 从它的最后一个滴答点向后,从重新加载开始的滴答点开始。主机比较 并排长跑应该提高 maxTicks 两者都适合。

标记使呈现它的程序返回到重新加载之前的标记 调度运行旧程序。

起源

每次调用都会传递一个起源报告,所以每个tick origins 对于输出的每条记录, 模块和构建它的元素表达式的UTF-8字节跨度。 originOf(tick, pointer) 找到一条记录。这些映像需要它们的调试部分(generateNxIr({ debug: true })) 记录要有起源。通过 { origins: false } 关闭报告。

选项

createPreviewSession(program, component, props, options) 利用运行时的限制, maxOperations, maxInputSize, maxCallDepth 和 maxRangeLength,适用于每一个调用 会话使;预览运行模型可能已经编写的代码,所以设置它们。 maxInputSize 范围是什么 主持人通过,道具和批次;这个国家 setProps 重新装弹传递是 运行时自己的,不被测量。 maxTicks (默认值为1000)为树的边界:超过它,则为 没有子节点的当前路径上的“最老”标记将被删除,而当前路径则更长 那么这个极限是完整的。

版本与发布记录

@nx-lang/previewer 共发布 5 个版本,首次发布于 2026/10/18;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.10.0latest2026/11/021 天前
0.9.02026/10/268 天前
0.8.02026/10/1816 天前
0.0.02026/10/1816 天前
0.0.0-stage2026/10/1816 天前

关于 @nx-lang/previewer 的常见问题

@nx-lang/previewer 是什么?

不稳定的。在@nx-lang/ir-runtime上运行一个NX组件,作为一个无头预览会话:一个带有分支、处理程序调度、场景和热加载的时间轴。没有UI,没有框架。

如何安装 @nx-lang/previewer?

在项目目录运行 npm install @nx-lang/previewer,或使用 pnpm add / yarn add / bun add。

@nx-lang/previewer 支持 TypeScript 吗?

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

@nx-lang/previewer 支持 ESM 还是 CommonJS?

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

@nx-lang/previewer 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@nx-lang/previewer 可以商用吗?

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

@nx-lang/previewer 还在维护吗?

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