JSFiddle - React, Tailwind, and code Playground

by evgkch

JavaScript

class Cache {
	constructor(initialState){
  	this.state = initialState;
  }
  update(nextState){
  	this.state = Object.assign({}, this.state, nextState);
  }
}


// States
const SOLID = 'SOLID';
const LIQUID = 'LIQUID';
const GAS = 'GAS';

// Action types
const HEAT = 'HEAT';
const COOL = 'COOL';

// Transitions
const transitions = {
	[SOLID]: [
  	{
    	to: SOLID,
      when: (d) => [d.value <= 0],
    },
  	{
    	to: LIQUID,
      when: (d)=>[d.value > 0]
    },
  ],
  [LIQUID]: [
  	{
    	to: LIQUID,
      when: (d) => [
      	d.value >= 0,
        d.value <= 100,
      ],
    },
  	{
    	to: SOLID,
      when: (d)=>[d.value < 0]
    },
  	{
    	to: GAS,
      when: (d)=>[d.value > 100]
    }
  ],
  [GAS]: [
  	{
    	to: GAS,
      when: (d) => [d.value >= 100],
    },
  	{
    	to: LIQUID,
      when: (d)=>[d.value < 100]
    }
  ],
};


/* const actions = {
  [HEAT]: cache => ({	value: cache.value + 1 }),
  [COOL]: cache => ({	value: cache.value - 1 })
}; */

// Actions
const heat = cache=>({
	type: HEAT,
  payload: { value: cache.value + 1 }
});

const cool = cache=>({
	type: COOL,
  payload: { value: cache.value - 1 }
});

const reducer = (cache, action)=>{
	const exp = 'heat: solid -> liquid, ';
	return {
  	[HEAT]: [
    	{
      	from: '*',
        to: '*', 
      },
    	['*', '*'],
      [SOLID, LIQUID],
      [LIQUID, GAS],
    ],
    [COOL]: [
    	['*', '*'],
      [GAS, LIQUID],
      [LIQUID, SOLID],
    ]
  };
	switch(action.type)
  {
  case HEAT:
  case COOL:
  	return Object.assign({}, cache, action.payload);
  default:
  	return;
  }
};

// FSM
function createFSM({ cache, reducer, transitions, initialState }){
  let currentState = initialState;

  const findTransitionFor = (...args)=>{
    return transitions[currentState].find(({ when })=>{
      return when(...args).every((condition)=>condition);
    });
  };
  
  const dispatch = (action) => {
  	const nextCache = reducer(cache.state, action);
    if (nextCache)
    {
    	const...