By default, a state machine tracks only its current state. If you want to track state history, you can extend the state machine using the state-machine-history plug-in.

  var StateMachineHistory = require('javascript-state-machine/lib/history')
Copy the code

  var fsm = new StateMachine({
    init: 'A'.transitions: [{name: 'step'.from: 'A'.to: 'B' },
      { name: 'step'.from: 'B'.to: 'C' },
      { name: 'step'.from: 'C'.to: 'D'}].plugins: [
      new StateMachineHistory()     // <-- plugin enabled here
    ]
  })

  fsm.history;        // [ 'A' ]
  fsm.step();
  fsm.history;        // [ 'A', 'B' ]
  fsm.step();
  fsm.history;        // [ 'A', 'B', 'C' ]

  fsm.clearHistory();

  fsm.history;        // [ ]

Copy the code

Backtracking history

You can use the historyBack and historyForward methods to trace back:

  var fsm = new StateMachine({
    init: 'A'.transitions: [{name: 'step'.from: 'A'.to: 'B' },
      { name: 'step'.from: 'B'.to: 'C' },
      { name: 'step'.from: 'C'.to: 'D' }
    ]
  })

  fsm.step();
  fsm.step();
  fsm.step();

  fsm.state;    // 'D'
  fsm.history;  // [ 'A', 'B', 'C', 'D' ]

  fsm.historyBack();

  fsm.state;    // 'C'
  fsm.history;  // [ 'A', 'B', 'C' ]

  fsm.historyBack();

  fsm.state;    // 'B'
  fsm.history;  // [ 'A', 'B' ]

  fsm.historyForward();

  fsm.state;    // 'C'
  fsm.history;  // [ 'A', 'B', 'C' ]
Copy the code

You can use the following properties to test whether history traversal is allowed

  fsm.canHistoryBack;     // true/false
  fsm.canHistoryForward;  // true/false
Copy the code

A complete set of lifecycle events still applies in historyBack and historyForward traversing history.

Set the historical record upper limit

By default, the state machine history is infinite and will continue to grow until purged. By configuring the plug-in, you can limit storage to the last N states:

  var fsm = new StateMachine({
    plugins: [
      new StateMachineHistory({ max: 100 })      // <-- plugin configuration]})Copy the code

Custom history

If the term history conflicts with an existing state machine property or method, you can give your plug-in a different name:

  var fsm = new StateMachine({
    init: 'A'.transitions: [{name: 'step'.from: 'A'.to: 'B' },
      { name: 'step'.from: 'B'.to: 'C' },
      { name: 'step'.from: 'C'.to: 'D'}].plugins: [
      new StateMachineHistory({ name: 'memory' })
    ]
  })

  fsm.step();
  fsm.step();

  fsm.memory;         // [ 'A', 'B', 'C' ]

  fsm.memoryBack();
  fsm.memory;         // [ 'A', 'B' ]

  fsm.memoryForward();
  fsm.memory;         // [ 'A', 'B', 'C' ]

  fsm.clearMemory();
  fsm.memory;         // [ ]
Copy the code