@fluixi/ devtools (英语)
Fluixi反应图的现场督察 文书 signal 编号 : memo 编号 : effect,然后将
依赖图和表传播活性: 状态 – 备忘录 – 效果,无故障,懒惰.
import { createReactor, createGraphView, DEVTOOLS_CSS } from '@fluixi/devtools';
const reactor = createReactor();
reactor.run(({ createSignal, createMemo, createEffect }) => {
const [count, setCount] = createSignal(0, { name: 'count' });
const double = createMemo(() => count() * 2, undefined, { name: 'double' });
createEffect(() => console.log(double()), { name: 'log' });
setInterval(() => setCount((n) => n + 1), 1000);
});
const view = createGraphView(svgEl);
const tick = () => { reactor.sample(); view.update(reactor.graph); requestAnimationFrame(tick); };
tick();
如何运作
乐器 createSignal编号 :createMemo编号 :createEffect 包装真实 @fluixi/reactive
原始的 原始的 原始的 读取是
订阅,所以边缘从实际读取记录: 这是真正的依赖图,而不是一个
重建项目。 值会被重新读取未跟踪到的每个帧,效果会算出自己的重运行,所以
检查官的动画正像核心所传播的那样.
观看你没有写的应用程序
创建Reactor手取出自己的原始人,所以它只看到针对他们的代码. 观察 Graph () 查看一个普通的应用程序: 运行时报告每个节点的制作情况, 图表从平面填充 import { signal } from '@fluixi/core'。在应用的模块装入前调用它:在图中不包含早先制作的节点.
import { observeGraph, createGraphView } from '@fluixi/devtools';
const observed = observeGraph();
await import('./src/main.js');
const view = createGraphView(svgEl);
const tick = () => { observed.sample(); view.update(observed.graph); requestAnimationFrame(tick); };
tick();
同样的地图 < 数字, RNode> 反应器生产, 所以创建 GraphView 和任何其他读出该图表的人并不在意是什么。 依赖被从核心节点上读取,核心节点已经保留了自己的来源和观察者,所以没有被包裹,也没有被截取到读取.
没有写出边框, 因为没有一个记录是当设置器被发射时运行的 。 渲染效果被忽略:多姆层使每个捆绑一个. 未观察的运行时间支付每个节点创建和重算一次无效检查.
把图表移到别的地方
将Graph将图表平放到json,Sets变成数组,活的核心节点变成版本和状态,读取器被放下,快照ToRenderMap把它反转成视图所画的东西. 样本( ) 返回移动的, 因此三角洲与这些 ID 是同一个调用, 并应用 Snapshot 将一个折叠成一个已经在屏幕上的图形 .
安装DevtoolsHook () 是为应用程序无法导入的工具 。 它留下了全局;当应用程序的运行时间加载时,它会找到它并交出自己的注册功能,因此图由应用的复制的框架而不是工具的来构建. 它必须在应用程序运行前被安装,是文件 start的浏览器代理,因为运行时间提供过一次. 它也不利于生产建筑,没有名字或地点.
import { installDevtoolsHook } from '@fluixi/devtools';
const hook = installDevtoolsHook(); // before the app loads
// …the app runs…
hook.snapshot(); // everything
hook.snapshot({ partial: true }); // only what moved since the last call
读取边值在行程中幸存下来;在被观测到的图上不存在写取边值,因为没有记录显示一个设置器被发射时正在运行计算.
节点从哪里来
一个图表节点可以携带一个可选的来源:作者创建它的地方的文件,行和列,加上来源给出一个时的可变名称. 每个字段都可以选取,而编译器没有看到整个节点的缺失.
编译器标记每个创建站点时 sourceLocations 正在运行,标记将文件和位置命名为来自原始源而不是生成的输出,而被仪器原始取出标记并保存在节点上:
// what the compiler emits in development
globalThis.__fx_source?.("src/App.ts", 10, 15, "count");
const count = signal(0);
一个渲染器不需要其他的,没有编译器,没有源文件,没有灰烬,并且文件,行和列足够一个主机决定如何打开. 例如:
for (const node of reactor.graph.values()) {
if (node.source) {
console.log(node.label, `${node.source.file}:${node.source.line}:${node.source.column}`);
}
}
编译器将每个组件包裹在备忘中,因此图中看到是包而不是组件. 含有组件名称的节点报告为 component 并将此名称作为它的标签,所以图表读作 App 而不是说 m5。没有任何关于节点变化的内容:它是同一个备忘录,有相同的依赖性.
组件节点 source 它的标记是写的地方, 也就是节点是写的地方: 相同的意思 source 所有其它种类的. declaredAt 是组件本身被宣布的地方,通常是另一个文件。 它代表着 source 当没有标记标记时,两个共享名称的组件报告没有位置,而不是错误的.
编译器无法看到节点
对于原始建筑在运行时间,呼叫 markReactiveSource 在它之前,因为下一个节点 创造了标记:
import { markReactiveSource } from '@fluixi/devtools';
markReactiveSource('src/factory.ts', 8, 2, 'fromFactory');
const s = signal(0);
生产建筑应该离开 sourceLocations 关了,然后不携带任何。 一个陈述有一个标记,所以 signal(compute(signal(1))) 标出内调并让外出裸露,而不是给它一个非自己位置.
API 密码
createReactor()→{ graph, run(setup), sample(), dispose() }observeGraph()→{ graph, sample(), detach() }installDevtoolsHook()· 全球工具通过serializeGraph(graph, now?, { ids, removed }?)编号 :snapshotToRenderMap(snapshot)applySnapshot(graph, snapshot): 将完整的快照或三角形折叠到绘图中formatValue(value, limit?): 任何值的可打印渲染; 从未丢出createGraphView(svg)→{ update(graph, now?), clear() }DEVTOOLS_CSS: 默认主题字符串(覆盖fx-*类以重排)