Skip to content

A javascript finite state machine library written in typescript heavily inspired by jakesgordon/javascript-state-machine

Notifications You must be signed in to change notification settings

giacomodeliberali/typed-state-machine

Repository files navigation

Typed State Machine

A library to describe finite state machine (aka DFAs).

tsm = await new TypedStateMachine({
    // minimal setup: initial state and transitions
    initialState: ThreadStateType.New,
    transitions: [
        new Transition({
            from: ThreadStateType.New,
            to: ThreadStateType.Ready,
            name: "wake_up"
        }),
        new Transition({
            from: ThreadStateType.Ready,
            to: ThreadStateType.Running
            name: "schedule"
        }),
        new Transition({
            from: ThreadStateType.Running,
            to: [
                ThreadStateType.Ready,
                ThreadStateType.Waiting,
                ThreadStateType.Terminated
            ]
        }),         
        new Transition({
            from: ThreadStateType.Waiting,
            to: ThreadStateType.Ready,
            name: "wake_up",

            //optional transition events
            onBeforeTransition: (tsm) => console.log(tsm.getState()),
            onAfterTransition: (tsm) => console.log(tsm.getState())
        })
    ],

    // general state events
    onStateEnter: (tsm, state) => console.log(`Entered in state ${ThreadStateType[state]}`),
    onStateLeave: (tsm, state) => console.log(`Left state ${ThreadStateType[state]}`),

    // general transition events
    onAfterEveryTransition: (tsm, from, to) => console.log(`After transition ${ThreadStateType[from]} -> ${ThreadStateType[to]}`),
    onBeforeEveryTransition: (tsm, from, to) => console.log(`Before transition ${ThreadStateType[from]} -> ${ThreadStateType[to]}`),

    // specific state async hooks
    hooks: [
        {
            state: ThreadStateType.Running,                 // state for this hooks
            handlers: [
                {
                    hookType: StateHookType.OnBeforeEnter,  // 4 possible values
                    handler: () => checkResources()         // returns Promise<boolean>
                }
            ]
        }
    ]
}).initialize();

Transit by name:

tsm.getState(); // ThreadStateType.New

await tsm.transitByName("wake_up")  // ThreadStateType.Ready

await tsm.transitByName("schedule") // ThreadStateType.Running

await tsm.transitByName("stop")     // ThreadStateType.Waiting

await tsm.transitByName("wake_up")  // ThreadStateType.Ready

// ...

Note

Please note that this project is under active development and is not ready for use.

Roadmap

  • Improve source code (refactoring)
    • Find a better way to make sync and async hooks compatible
      • Maybe divide function in version to keep strong types? Eg.
        • transit(): sync, throw error if it finds an async hook in the current resolution
        • await transitAsync() // ok for both sync and async hooks
        • transitByName()
        • await transitByNameAsync()
        • goto()
        • await gotoAsync()
    • Refactor HookFunction<T>to something more significant
    • Consider remove new Transition({}) in favour of {}like other options
    • Add other utility methods:
      tsm.bindHook(StateType.A, (hookType: StateHookType) => {
          if(hookType == StateHookType.OnBeforeLeave){
              // ...
          }
      });
    • Transit by name (with context-awareness)
      tsm.transit("transitionName")
    • Add options to ignore hooks and events
      tsm.transit(MyState.NewState, invokeLifecycles: bool)
    • Keep track of previous states
      tsm.back();
      tsm.forward();
    • Add more information in fired events
      transition.onBeforeTransition(tsm: TypedStateMachine, from: T, to: T);
      transition.onAfterTransition(tsm: TypedStateMachine, from: T, to: T);
  • Improve unit test organization
  • Add support to decorate an enum with reflect-metadata
        enum StateType {
    
            @Transition({
                to: [
                    StateType.Inactive,
                    StateType.Paused
                ]
            })
            Active,
    
            @Transition({ ... })
            Paused,
    
            @Transition({ ... })
            Inactive,
    
            @Transition({ ... })
            Stopped
        }
    
        const tsm = new TypedStateMachine(StateType);
    
        tsm.bindHook(StateType.A, (hookType: StateHookType) => {
            if(hookType == StateHookType.OnBeforeLeave){
                // ...
            }
        });
  • Add pluggable modules
    • History
    • Visualization
    • ...

About

A javascript finite state machine library written in typescript heavily inspired by jakesgordon/javascript-state-machine

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published