The State Pattern

First, if you are not familiar with this pattern, I recommend you read this excellent article.

Our Master-Class types include an M.State type. That type helps us turn objects into concurrent, hierarchical state machines.

The M.State type basically merges object types together

let MyClass = M({
  state: M.State([
    {
      delegate: M({n: 3}), // (1) first object type
      subState: [{
        delegate: M({m: 5}) // (1.1) first object type child
      }]
    },
    {
      delegate: M({s: String}) // (2) second object type
    }
  ])
});
let myInstance = new MyClass();
assert.deepEqual(myInstance.state, {n: 3, m: 5, s: ''});

but every merge can be conditional using the when option

MyClass = M({
  flag1: true,
  state: M.State([
    {
      when() {return this.flag2;},
      delegate: M({n: 3}), // (1) first object type
      subState: [{
        when() {return this.root.flag1;},
        delegate: M({m: 5}) // (1.1) first object type child
      }]
    },
    {
      delegate: M({ // (2) second object type
        flag2: Boolean,
        s: String
      })
    }
  ])
});
myInstance = new MyClass();
assert.deepEqual(myInstance.state, {flag2: false, s: ''});

Note that myInstance.state.m property is not included, even though this.root.flag1 is true. This is because its parent state is blocked on this.flag2. Now, if we just assign myInstance.state.flag2 = true, we'll get

assert.deepEqual(
  myInstance.state, 
  {flag2: true, s: '', n: 3, m: 5}
);

results matching ""

    No results matching ""