# Changelog
## 0.1.0.0 -- unreleased
First release.
- `scxml` declaration quasiquoter generating `FsmState`, `FsmEvent`,
`fsmChart`, `initiateStateMachine` and `notifyStateMachine`.
- Hierarchy (compound states as sum types), parallel regions (as products),
`<onentry>` and `<onexit>` callbacks named in the XML, entry callbacks that
raise events, and SCXML `done.state.X` completion events.
- Unmatched events leave the state unchanged, as in SCXML.
- Compile-time validation: strict XML (via `xml-conduit`), state ids, event
names, callback names, a level rule requiring a transition to target a
sibling of its source, and a rule forbidding transitions on a region of a
`<parallel>`. `initial` is required on every compound state and must name a
direct child; SCXML's "first child in document order" default is not
supported.
- The evaluator is a single recursive pass over the tree. Because a transition
may only target a sibling, a state only ever rearranges its own children, so
there are no least common ancestors, exit-set filters over the whole
configuration, or conflicts between transitions at different depths. The
derived index is gone, along with lookup by id, parent links and document
order. Innermost-wins is now explicit: children are asked first and a state
acts only if nothing below it did.
- A `<final>` state is rejected as a direct region of a `<parallel>`. SCXML
does not allow it, and it used to report the whole parallel complete before
the other regions had run.
- The chart is a tree: a state owns its children as `Node`s, and a compound
state keeps its initial child first, so a dangling child, a disagreeing
parent and an initial child that is not one of its own are all
unrepresentable. Parent and document order are derived into an index rather
than stored. A compound state's initial child is therefore its first
generated constructor, which changes derived `Ord` for charts that do not
write the initial state first.
Only the interpreter needs the derived index; the parser and the generator
walk the tree, so a transition target is checked against the source's
siblings rather than by looking up parents.
- `done.state.X` may only be handled on `X` itself, so completion climbs one
level at a time through `<final>` states and validation is entirely local to
a state and its neighbours.
- A transition on an enclosing state acts as a default that an inner state can
override, since the innermost matching transition wins and only it is taken.
Documented rather than warned about: a Template Haskell warning becomes an
error under `-Werror` and cannot be exempted by flag.
- The public API is the `scxml` quasiquoter alone. `serializeStateMachine` and
`deserializeStateMachine` are generated into the calling module, so a chart
needs no other import. The remaining modules are not exposed.
- Transitions are a map from event name to target, so two transitions on one
state for the same event are unrepresentable, and document order never
decides which transition is taken. A transition naming more than one target
is rejected; both previously compiled and silently produced a wrong state.
- `Kind` carries each state's children, so an atomic or final state with
children, a compound state without an initial child, and a `<parallel>`
without regions are all unrepresentable rather than merely rejected.
- `Show`/`Read` on every generated type, and `toStateIds`/`fromStateIds` for
storing a state outside Haskell as the SCXML configuration.