TypeState icon indicating copy to clipboard operation
TypeState copied to clipboard

[Feature] define fluent transitions with junction support for multiple paths and also fluent transitions itself

Open spali opened this issue 9 years ago • 0 comments

I adapted your code to support a second level of states but stripped some other stuff out which I don't need, so this is why I don't just send a complete code of mine. But I tried to extract the important part, with it you should be able to introduce this feature without a lot of work. The only problem is, because I stripped it down to only allow to provide a single state per transition, I don't know how easy it is to adapt it for multiple states. But even you get it, I think due the advantage of the incredible nice reading code by fluent chaining multiple transitions with junctions , would go away if you use this feature with multiple states. I didn't get it to be readable and always clear which transitions are possible with multiple states per transition. Probably you provide an separate Transition interface and API for single fluent definition to keep your API backward compatible.

But with single states it makes really fun to read the flow of the states as defined. And yes, due your duplicate check in the code, you can just for fun define duplicate transitions to keep the flow nice and easy to red.

i.e.

fsm.from(State.disconnected)
  .to(State.connecting)
  .to(State.connected)
  .to(State.disconnecting)
  .toMulti(
    from => from
      .to(State.autoReconnect)
      .to(State.connecting)
      .to(State.connected)
   ,from => from
      .to(State.disconnected)
   .....
   );
export class Transitions<T> {
...
  /**
   * Specify the end state(s) of a transition function
   */
  public to(state: T): Transitions<T> {
    this.toState = state;
    this.fsm.addTransitions(this);
    return new Transitions<T>(this.fsm, this.toState);
  }

  /**
   * allows to fluent define a states switch transition to multiple allowed states from a single source state.
   * example:
   * fsm.from(State1)
   *   .toMulti(
   *    from => from.to(State1A).to ...
   *   ,from => from.to(State1B).to ...
   *   )
   */
  public toMulti(...from: ((from: Transitions<T>) => Transitions<T>)[]): Transitions<T> {
    from.forEach(fnc => {
      var x = new Transitions<T>(this.fsm, this.fromState);
      fnc.call(x, x);
    });
    return this;
  }

}

second:

just add a return this in the go() method allows to also fluently switch states like:

// connect
fsm
  .go(State.connecting)
  .go(State.connected);

// disconnect
fsm
  .go(State.disconnecting)
  .go(State.disconnected);

spali avatar Nov 21 '16 21:11 spali