Debugging
Use Inval's debug tools to trace invalidations and understand your graph.
Tracing with why()
When a node recomputes unexpectedly, use why() to trace the invalidation path back to the source.
debug-why.ts TYPESCRIPT
import { input, node, why } from '@blu3ph4ntom/inval'
const width = input(800)
const height = input(600)
const area = node({
dependsOn: { w: width, h: height },
compute: ({ w, h }) => w * h
})
width.set(1000)
why(area) // ['area', 'width']
// The path tells you: area was invalidated because width changed Inspecting Nodes
Use inspect() to see a node's current state, dirty flag, and connection count.
debug-inspect.ts TYPESCRIPT
const info = area.inspect()
// {
// id: 'node_3',
// name: 'area',
// type: 'computed',
// value: 600000,
// dirty: false,
// dependencyCount: 2,
// dependentCount: 0
// } Visualizing with toDot()
Export your graph as Graphviz DOT format and visualize it online.
debug-dot.ts TYPESCRIPT
import { input, node, toDot } from '@blu3ph4ntom/inval'
const a = input(1)
const b = input(2)
const c = node({ dependsOn: { a, b }, compute: ({ a, b }) => a + b })
console.log(toDot([c]))
// digraph G {
// "a" -> "c"
// "b" -> "c"
// }
// Paste output into graphviz.online to see the graph visually Monitoring with stats()
Track graph size and compute calls to monitor performance.
debug-stats.ts TYPESCRIPT
import { stats } from '@blu3ph4ntom/inval'
const s = stats([root])
// {
// nodeCount: 15,
// inputCount: 5,
// computedCount: 10,
// edgeCount: 20,
// totalComputeCalls: 42
// } Tip
Call stats() before and after operations to measure how many computations were triggered. A well-designed graph minimizes totalComputeCalls.