Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

State & Logic Nodes

All state in Voce IR is modeled as explicit, typed finite state machines. There are no implicit closures, dependency arrays, or hook ordering. The compiler can statically analyze every possible state transition.

StateMachine

A named finite state machine with typed states, transitions, guards, and effects. Every component’s behavior is a state machine. The validator checks reachability (no dead states) and deadlock freedom.

State

FieldTypeRequiredDescription
namestringyesState name
initialboolnoWhether this is the initial state (default false)
terminalboolnoWhether this is a final state (default false)

Transition

FieldTypeRequiredDescription
eventstringyesEvent name that triggers this transition
fromstringyesSource state name
tostringyesTarget state name
guardstringnoReference to a ComputeNode that returns bool
effectstringnoReference to an EffectNode to execute on transition

StateMachine

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name (e.g., “auth-flow”)
states[State]yesList of states
transitions[Transition]yesList of transitions
{
  "node_id": "btn-state",
  "name": "button-state",
  "states": [
    { "name": "idle", "initial": true },
    { "name": "hovered" },
    { "name": "pressed" },
    { "name": "disabled", "terminal": true }
  ],
  "transitions": [
    { "event": "hover", "from": "idle", "to": "hovered" },
    { "event": "unhover", "from": "hovered", "to": "idle" },
    { "event": "press", "from": "hovered", "to": "pressed" },
    { "event": "release", "from": "pressed", "to": "idle", "effect": "submit-effect" }
  ]
}

DataNode

Declares an external data dependency. The compiler emits fetch code with caching, error handling, and loading states.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
sourceDataSourceyesEndpoint configuration
cache_strategyCacheStrategynoNone, StaleWhileRevalidate (default), CacheUntilInvalidated, Static
stale_timeuint32noFreshness duration in ms (default 30000)
cache_timeuint32noCache retention in ms (default 300000)
cache_tags[string]noTags for cache invalidation
auth_requiredboolnoWhether authentication is needed (default false)
loading_state_machinestringnoStateMachine tracking loading/error/success
query_params[KeyValue]noQuery parameters for filtering, sorting, pagination

DataSource

FieldTypeRequiredDescription
providerDataSourceProvidernoRest (default), GraphQL, Supabase, Firebase, Convex, Custom
endpointstringnoAPI endpoint URL
resourcestringnoResource path or query
methodHttpMethodnoGET (default), POST, PUT, PATCH, DELETE
headers[KeyValue]noCustom request headers
{
  "node_id": "user-data",
  "name": "current-user",
  "source": {
    "provider": "Rest",
    "endpoint": "/api/users/me",
    "method": "GET"
  },
  "cache_strategy": "StaleWhileRevalidate",
  "stale_time": 60000,
  "auth_required": true
}

ComputeNode

A pure function from inputs to output. Referentially transparent, so the compiler can memoize or pre-compute at build time.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
inputs[ComputeInput]yesInput bindings from other nodes
expressionstringyesExpression to evaluate
output_typestringnoOutput type hint for the compiler

ComputeInput

FieldTypeRequiredDescription
namestringyesParameter name in the expression
source_node_idstringyesSource DataNode, ContextNode, or ComputeNode
field_pathstringnoDot-path into the source data
{
  "node_id": "total-compute",
  "name": "order-total",
  "inputs": [
    { "name": "price", "source_node_id": "product-data", "field_path": "price" },
    { "name": "qty", "source_node_id": "cart-ctx", "field_path": "quantity" }
  ],
  "expression": "price * qty",
  "output_type": "number"
}

EffectNode

A side effect triggered by a state transition. Effects attach to transitions, never to states, eliminating mount/unmount ambiguity.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
effect_typeEffectTypenoAnalytics, ApiCall, Storage, Haptic, Log, Navigate, Custom
config[KeyValue]noConfiguration payload
api_sourceDataSourcenoEndpoint configuration for ApiCall effects
idempotentboolnoWhether safe to retry (default false)
{
  "node_id": "track-click",
  "name": "analytics-click",
  "effect_type": "Analytics",
  "config": [
    { "key": "event", "value": "button_click" },
    { "key": "category", "value": "cta" }
  ]
}

ContextNode

Shared state scoped to a subtree. Replaces React Context, Redux, and prop drilling. Typed with explicit read/write boundaries.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringyesContext name
initial_valuestringnoInitial value as JSON string
writers[string]noNode IDs allowed to write (empty = any descendant)
globalboolnoIf true, not scoped to subtree (default false)
{
  "node_id": "cart-ctx",
  "name": "shopping-cart",
  "initial_value": "{ \"items\": [], \"quantity\": 0 }",
  "global": true
}