@getflourish/xstate-markdown-compiler
v0.1.2
Published
Compile XState Markdown DSL to XState v5 machine code
Readme
@getflourish/xstate-markdown-compiler
Compile an XState-flavored Markdown DSL (machine.md / *.machine.md) into XState v5 machine code.
This DSL is optimized for fast writing of state machines in real-time collaboration (for example, while whiteboarding in meetings), then compiling that draft into production-ready XState code.
Why this format
- write states and transitions quickly without TypeScript boilerplate
- iterate live with teammates in plain text
- compile to consistent, reviewable machine code
- progressively add bindings, guards, context, and action effects as the design matures
Install
pnpm add -D @getflourish/xstate-markdown-compilerCLI usage
Compile a single file:
xstate-markdown-compile src/machines/hand-detector.machine.md --ext=tsCompile all machine.md / *.machine.md files under a directory:
xstate-markdown-compile src --ext=tsWatch mode:
xstate-markdown-compile src --ext=ts --watchJavaScript API
import { parse, compile } from "@getflourish/xstate-markdown-compiler";
const source = `
id: demoMachine
States:
IDLE (initial)
ACTIVE
Transitions:
IDLE -> ACTIVE on START
ACTIVE -> IDLE on STOP
`;
const ast = parse(source);
if (ast.errors.length) {
console.error(ast.errors);
} else {
const output = compile(ast);
console.log(output);
}DSL examples
1) Minimal state machine
id: toggle
States:
OFF (initial)
ON
Transitions:
OFF -> ON on TOGGLE
ON -> OFF on TOGGLE2) Services + action/guard bindings
id: alarmMachine
Services:
device from "@/services/device"
settings from "@/services/settings"
Action Bindings:
ringAlarm = device.ring
stopAlarm = device.stop
Guard Bindings:
isAlarmEnabled = settings.isAlarmEnabled
States:
IDLE (initial)
ALARM entry: ringAlarm if isAlarmEnabled exit: stopAlarm if isAlarmEnabled
Transitions:
IDLE -> ALARM on TRIGGER
ALARM -> IDLE on DISMISS3) Context + assign action effects
id: counter
Context:
count: number = 0
Action Effects:
increment = assign count = context.count + 1
resetCount = assign count = 0
States:
READY (initial)
Transitions:
READY -> READY on INC do increment
READY -> READY on RESET do resetCount4) Comments and top-level notes
Counter machine used in onboarding flow
# Keep the machine simple and deterministic
id: counterWithComments
States:
# Start state
IDLE (initial)
RUNNING
Transitions:
# Begin counting
IDLE -> RUNNING on START
RUNNING -> IDLE on STOPTop-level comments are preserved at the top of compiled output, and section comments are attached to nearby generated code.
Output style
Compiler output uses:
setup({ guards, actions }).createMachine(...)- generated
contextwhen defined in DSL assign(...)forAction Effects- descriptive synthetic action names for guarded entry/exit actions
