API Reference
Complete reference for all exported functions and types.
input(value)
Creates a leaf input node. External code sets the value.
Signature
function input<T>(value: T): InputNode<T> Parameters
| Parameter | Type | Description |
|---|---|---|
value | T | Initial value of any type |
Returns
An InputNode<T> with methods:
get(): T— returns current valueset(value: T): void— updates value, marks dependents dirtyinvalidate(): void— forces invalidation of dependentsisDirty(): false— inputs are never dirtyinspect(): InspectInfo— debug informationdispose(): void— disconnect from graph
Example
const width = input(800)
width.get() // 800
width.set(600) // marks dependents dirty node(options)
Creates a computed node with declared dependencies. Lazy evaluation, cached results.
Signature
function node<DependsOn extends Record<string, Node<any>>, R>(
options: {
dependsOn: DependsOn
compute: (values: ResolvedValues<DependsOn>) => R
}
): ComputedNode<R> Options
| Property | Type | Description |
|---|---|---|
dependsOn | Record<string, Node> | Map of names to dependency nodes |
compute | (values) => R | Function that computes the result from resolved dependency values |
Returns
A ComputedNode<R> with methods:
get(): R— returns cached value or recomputes if dirtyisDirty(): boolean— true if any dependency changedinvalidate(): void— forces recompute on next get()inspect(): InspectInfo— debug informationdispose(): void— disconnect from graph
Example
const width = input(800)
const height = input(600)
const area = node({
dependsOn: { w: width, h: height },
compute: ({ w, h }) => w * h
})
area.get() // 480000
area.get() // 480000 (cached)
width.set(1000)
area.get() // 600000 (recomputed) Important
The compute function must be pure. No side effects. It may be called multiple times or not at all depending on cache state.
batch(fn)
Executes a function atomically. All input sets within the batch trigger a single invalidation walk. Returns the set of changed nodes.
Signature
function batch<T>(fn: () => T): T | Set<Node<any>> Example
const changed = batch(() => {
width.set(1000)
height.set(800)
})
// changed = Set of all dirtied nodes why(node)
Traces the invalidation path for a node. Returns an array of node names from the target back to the source inputs that caused invalidation.
Signature
function why(node: Node<any>): string[] Example
const cardHeight = node({
dependsOn: { textHeight, padding },
compute: ({ textHeight, padding }) => textHeight + padding
})
width.set(400) // triggers textHeight recompute
why(cardHeight) // ['cardHeight', 'textHeight', 'width'] ancestors(node) / descendants(node)
Navigate the dependency graph. ancestors returns all upstream dependencies. descendants returns all downstream dependents.
Signature
function ancestors(node: Node<any>): Set<Node<any>>
function descendants(node: Node<any>): Set<Node<any>> Example
const a = input(1)
const b = node({ dependsOn: { a }, compute: ({ a }) => a * 2 })
const c = node({ dependsOn: { b }, compute: ({ b }) => b + 1 })
ancestors(c) // Set { b, a }
descendants(a) // Set { b, c } toDot(nodes)
Exports the dependency graph as Graphviz DOT format for visualization.
Signature
function toDot(nodes: Node<any>[]): string Example
console.log(toDot([area]))
// Output:
// digraph G {
// "width" -> "area"
// "height" -> "area"
// }
// Paste to graphviz.online to visualize stats(nodes)
Returns statistics about the dependency graph.
Signature
function stats(nodes: Node<any[]>): {
nodeCount: number
inputCount: number
computedCount: number
edgeCount: number
totalComputeCalls: number
} Example
stats([root])
// {
// nodeCount: 5,
// inputCount: 2,
// computedCount: 3,
// edgeCount: 4,
// totalComputeCalls: 12
// } TypeScript Types
InputNode<T>
interface InputNode<T> {
get(): T
set(value: T): void
invalidate(): void
isDirty(): false
inspect(): InspectInfo
dispose(): void
} ComputedNode<T>
interface ComputedNode<T> {
get(): T
isDirty(): boolean
invalidate(): void
inspect(): InspectInfo
dispose(): void
} InspectInfo
interface InspectInfo {
id: string
name: string
type: 'input' | 'computed'
value?: any
dirty: boolean
dependencyCount: number
dependentCount: number
}