Other Decorators
Besides @ChangeState, AFSM provides three decorators for different state-constraint scenarios.
@Includes — include-state guard
Only allow the method to be called when in one of the specified states.
import { Includes } from 'afsm'
class Player extends FSM { @Includes('playing') pause() { // only callable in the playing state // otherwise throws FSMError }}Signature:
function Includes(...states: string[]): MethodDecoratorMultiple states: @Includes('playing', 'buffering').
@Excludes — exclude-state guard
Disallow calling the method in the specified states.
import { Excludes } from 'afsm'
class Player extends FSM { @Excludes('disabled') play() { // callable in any state except disabled }}Signature:
function Excludes(...states: string[]): MethodDecorator@ActionState — action state
Temporarily switch to a state during async execution, then return to the original state after.
import { ActionState } from 'afsm'
class Doc extends FSM { @ActionState('saving') async save() { await persist() // during execution the state is 'saving'; after, it returns to the original }}Signature:
function ActionState(name?: string): MethodDecoratorIf name is omitted, the method name is used as the state name.
vs @ChangeState
@ChangeState | @ActionState | |
|---|---|---|
| Before execution | validates from | no validation, switches directly |
| After execution | enters new stable state to | returns to original state |
| Intermediate | MiddleState (${action}ing) | enters name directly |
| Appears in stateDiagram | ✅ | ❌ |
Combining decorators
Decorators can stack, applied bottom-up:
class Service extends FSM { @Includes('idle') // outer: validate state first @ChangeState('idle', 'done') // inner: then transition async fetch() {}}Usually you’ll use them individually.