| name | statepro |
| description | Quantum state machine library (Go) with visual studio editor. Use when: working with statepro imports (github.com/rendis/statepro), writing or editing state machine JSON definitions, creating universes/realities/transitions, registering observers/actions/invokes/conditions, handling superposition/collapse mechanics, using the debugger CLI/TUI or automation bot, integrating the studio visual editor (@rendis/statepro-studio-react or statepro-studio web component), validating machine definitions against JSON schema, managing machine snapshots, or any task involving quantum machine models, event routing, accumulator patterns, or the statepro ecosystem. |
StatePro — Quantum State Machine Library
Go library for multi-universe state machines with superposition. Three layers: theoretical/ (models), instrumentation/ (interfaces), experimental/ (runtime). Visual editor via studio/.
Terminology
| Quantum Metaphor | Traditional FSM | Description |
|---|
| QuantumMachine | State Machine | Top-level container, multiple universes |
| Universe | Independent FSM | Self-contained state machine with own current state |
| Reality | State | A state within a universe |
| Transition | Edge | Movement between realities, triggered by events |
| Superposition | — | Universe has no concrete reality; accumulates events until observer collapses |
| Observer | — | Guard that watches accumulated events, triggers collapse |
| Action | Side Effect (sync) | Synchronous operation on entry/exit/transition |
| Invoke | Side Effect (async) | Fire-and-forget async operation |
| Condition | Guard | Boolean check on a transition |
| Universal Constants | Global Hooks | Actions/invokes that execute on ALL entries/exits/transitions |
| Accumulator | — | Collects events during superposition for observer evaluation |
Machine Definition Quick Reference
Minimal valid machine (one universe, two realities):
{
"id": "my-machine",
"canonicalName": "my-machine",
"version": "1.0.0",
"initials": ["U:my-universe"],
"universes": {
"my-universe": {
"id": "my-universe",
"canonicalName": "my-universe",
"version": "1.0.0",
"initial": "IDLE",
"realities": {
"IDLE": {
"id": "IDLE",
"type": "transition",
"on": {
"start": [{ "targets": ["RUNNING"] }]
}
},
"RUNNING": {
"id": "RUNNING",
"type": "final"
}
}
}
}
}
Reality types: transition (intermediate), final (successful end), unsuccessfulFinal (failed end).
Transition types: default (abandon current reality), notify (send to target WITHOUT leaving current reality).
Target formats: "RealityID" (internal), "U:UniverseID" (external universe), "U:UniverseID:RealityID" (external universe at specific reality).
For complete schema, all fields, and validation rules see references/machine-definition.md.
Go API Quick Reference
import (
"github.com/rendis/statepro/v3"
"github.com/rendis/statepro/v3/builtin"
"github.com/rendis/statepro/v3/instrumentation"
)
builtin.RegisterAction("myAction", func(ctx context.Context, args instrumentation.ActionExecutorArgs) error {
machineCtx := args.GetContext().(*MyContext)
return nil
})
jsonBytes, _ := os.ReadFile("state_machine.json")
model, _ := statepro.DeserializeQuantumMachineFromBinary(jsonBytes)
qm, _ := statepro.NewQuantumMachine(model)
ctx := context.Background()
machineCtx := &MyContext{}
qm.Init(ctx, machineCtx)
event := statepro.NewEventBuilder("start").
SetData(map[string]any{"key": "value"}).
Build()
handled, err := qm.SendEvent(ctx, event)
snapshot := qm.GetSnapshot()
qm.LoadSnapshot(snapshot, machineCtx)
For full API reference, all interfaces, and executor signatures see references/go-api.md.
Executor Registration
builtin.RegisterObserver(src string, fn instrumentation.ObserverFn) error
builtin.RegisterAction(src string, fn instrumentation.ActionFn) error
builtin.RegisterInvoke(src string, fn instrumentation.InvokeFn) error
builtin.RegisterCondition(src string, fn instrumentation.ConditionFn) error
Src pattern: ^\S+$ (no whitespace). Convention: "myObserver" or "namespace:name".
Function Signatures
type ObserverFn func(ctx context.Context, args ObserverExecutorArgs) (bool, error)
type ActionFn func(ctx context.Context, args ActionExecutorArgs) error
type InvokeFn func(ctx context.Context, args InvokeExecutorArgs)
type ConditionFn func(ctx context.Context, args ConditionExecutorArgs) (bool, error)
All executor args provide: GetContext(), GetRealityName(), GetUniverseCanonicalName(), GetUniverseId(), GetEvent(), GetUniverseMetadata(), AddToUniverseMetadata(key, value).
ActionExecutorArgs additionally provides: GetSnapshot(), EmitEvent(name, data) (entry actions only, FIFO, max depth 10).
Built-in Behaviors
Observers
| Src | Args | Behavior |
|---|
builtin:observer:containsAllEvents | {"p1":"evt1","p2":"evt2"} | True if ALL named events accumulated |
builtin:observer:containsAtLeastOneEvent | {"p1":"evt1","p2":"evt2"} | True if ANY named event accumulated |
builtin:observer:alwaysTrue | none | Always returns true |
builtin:observer:greaterThanEqualCounter | {"evt1":3,"evt2":2} | True if each event appears >= N times |
builtin:observer:totalEventsBetweenLimits | {"minimum":2,"maximum":5} | True if total events within range |
Actions
| Src | Args | Behavior |
|---|
builtin:action:logBasicInfo | none | Logs actionType, reality, universe |
builtin:action:logArgs | any map | Logs basic info + arg keys and values |
builtin:action:logArgsWithoutKeys | any map | Logs basic info + arg values only |
builtin:action:logJustArgsValues | any map | Logs only arg values |
Superposition & Collapse
- Universe enters superposition when targeted externally or with multiple targets
currentReality = nil; events accumulate in Accumulator
- Observers on each reality evaluate accumulated events
- First observer returning
true collapses superposition to that reality
- Entry actions/invokes execute on the collapsed reality
always transitions evaluate after entry
EmitEvent (entry actions only): queue internal events processed FIFO after all entry actions complete. First event triggering an approved transition wins. Max nesting depth: 10.
Debugging
CLI TUI Debugger (Bubble Tea)
debugger := cli.NewStateMachineDebugger()
debugger.SetStateMachinePath("./state_machine.json")
debugger.SetEventsPath("./events.json")
debugger.SetSnapshotsPath("./snapshots.json")
debugger.Run(machineContext)
Views: Send Event (filterable list, sent/unsent status) | History (rollback support) | Load Snapshot | JSON Viewer.
Keys: enter send, esc back, v resume, m snapshots, t tracking, s context, r rollback.
Bot Automation
provider := func(snapshot *instrumentation.MachineSnapshot) (instrumentation.Event, error) {
return nextEvent, nil
}
b, _ := bot.NewBot(qm, provider, true)
b.Run(ctx, machineContext)
history := b.GetHistory()
For full debugger docs see references/debugger.md.
Studio Visual Editor
pnpm monorepo at studio/ with three packages:
studio/app — Standalone Vite dev shell (port 5173)
@rendis/statepro-studio-react — Core editor React library (npm)
@rendis/statepro-studio-web-component — <statepro-studio> custom element (npm)
Dev Commands
pnpm -C studio install
pnpm -C studio dev
pnpm -C studio dev:dist
pnpm -C studio build
pnpm -C studio test
pnpm -C studio typecheck
pnpm -C studio dev:doctor
React Integration
import { StateProEditor } from "@rendis/statepro-studio-react";
import "@rendis/statepro-studio-react/styles.css";
<StateProEditor
value={{ definition: machineJSON, layout: savedLayout }}
onChange={(payload) => {
// payload: { machine, layout, issues, canExport, source, at }
}}
features={{ json: { import: true, export: true } }}
locale="en"
/>
Web Component
import { defineStateProStudioElement } from "@rendis/statepro-studio-web-component";
import "@rendis/statepro-studio-react/styles.css";
defineStateProStudioElement();
const el = document.querySelector("statepro-studio");
el.value = { definition: machineJSON };
el.addEventListener("studio-change", (e) => console.log(e.detail));
For full studio docs (props, Tailwind setup, features, i18n) see references/studio.md.
Build & Test
Go (core library)
go build ./...
go test ./...
go test ./experimental/...
go test -run TestFuncName ./...
Studio
pnpm -C studio install
pnpm -C studio dev
pnpm -C studio build
pnpm -C studio test
pnpm -C studio/packages/editor-core test
pnpm -C studio/packages/editor-core build
Test descriptions are written in Spanish.