finished state machine using typescript
mecha-ts is a 0-dependency finished state machine ts compatible
Download nodejs first. Use npm to install get-ip-from-request.
npm i mecha-ts@latest
// machine.js
import { createMachine, guard, intermediate, reduce, state, transition } from "mecha-ts"
const STATES = Object.freeze({
LOGIN_SCREEN: 0,
HUB_SCREEN: 1,
GAME_SCREEN: 2
})
const EVENTS = Object.freeze({
LOGIN: 0,
LOGOUT: 1,
JOIN: 2,
PLAY: 3,
LEAVE: 4,
END_GAME: 5
})
const makeCtx = () => ({
pseudo: '',
room: '',
life: 0,
x: 0,
y: 0
})
// guard
const validPseudo = (ctx, e) => ctx?.pseudo !== e?.payload?.pseudo
const endGame = (ctx) => ctx?.life === 0
// reducer
const login = (ctx, e) => ({ ...ctx, pseudo: e?.payload?.pseudo ?? '' })
const initGame = (ctx) => ({ ...ctx, life: 3, x: 10, y: 10 })
const leaveGame = (ctx) => ({ ...ctx, life: 0, x: 0, y: 0, room: '' })
const play = (ctx, e) => ({
...ctx,
life: e?.payload?.life,
x: e?.payload?.x,
y: e?.payload?.y
})
const MyMachine = createMachine([
state(
STATES.LOGIN_SCREEN,
intermediate(EVENTS.LOGIN, guard(validPseudo), STATES.HUB_SCREEN, STATES.LOGIN_SCREEN, reduce(login))
),
state(
STATES.HUB_SCREEN,
transition(EVENTS.LOGOUT, STATES.LOGIN_SCREEN, reduce(makeCtx)),
transition(EVENTS.JOIN, STATES.GAME_SCREEN, reduce(initGame))
),
state(
STATES.GAME_SCREEN,
transition(EVENTS.LEAVE, STATES.HUB_SCREEN, reduce(leaveGame)),
transition(EVENTS.PLAY, STATES.GAME_SCREEN, reduce(play)),
transition(EVENTS.END_GAME, STATES.GAME_SCREEN, reduce(initGame), guard(endGame))
)
], makeCtx)
export { MyMachine }
mecha-ts is inspired by robot3 but mecha-ts and robot3 has some differences :
- mecha-ts use number for identify states and events, robot3 accept only string
- robot3 use invoke for async transition, mecha-ts haven't
...