XState Under The Hood

XState အလုပ်လုပ်ပုံ

Vanilla JavaScript နဲ့ State Machine ကို ဘယ်လို implement လုပ်လဲဆိုတာ ရှင်းပြပါမယ်

Introduction

XState က state machine တွေနဲ့ statechart တွေကို implement လုပ်ထားတဲ့ library တစ်ခုပါ။ ဒီမှာတော့ XState က နောက်ကွယ်မှာ ဘယ်လို အလုပ်လုပ်လဲ၊ ဘယ် algorithm တွေ၊ design pattern တွေ သုံးလဲဆိုတာကို vanilla JavaScript နဲ့ ရေးပြီး နားလည်အောင် ရှင်းပြပေးမှာပါ။

Core Concepts

XState က application logic ကို state machine အနေနဲ့ model လုပ်ပါတယ်။ state machine ဆိုတာ finite number of state တွေရှိပြီး၊ state တစ်ခုကနေ တစ်ခု transition လုပ်တဲ့ rule တွေကို define လုပ်ထားတဲ့ mathematical model ပါ။ machine တစ်ခု create လုပ်တဲ့အခါမှာ ဘာ state တွေရှိမယ်၊ ဘယ်လို transition လုပ်မယ်ဆိုတာကို configuration object နဲ့ describe လုပ်တာပါ။

Runtime

createMachine() ခေါ်တဲ့အခါ XState က ချက်ချင်း execute မလုပ်ပါဘူး။ machine definition (blueprint လိုမျိုး) ကို immutable အနေနဲ့ create လုပ်ပေးတာပါ။ တကယ့် execution က actor တစ်ခု create လုပ်မှ စပါတယ် - XState v5 မှာ createActor(machine) သုံးတယ်၊ v4 မှာ interpret(machine) သုံးတယ်။

// XState v5 (လက်ရှိ version)
const machine = createMachine({ /* config */ });
const actor = createActor(machine).start();

// XState v4 (ဟောင်း version)
const service = interpret(machine).start();

Actor (v4 မှာ service လို့ခေါ်တယ်) က runtime engine ပါ။ သူက:

  • လက်ရှိ state ကို track လုပ်တယ်

  • Event တွေကို process လုပ်တယ်

  • Side effect တွေ (actions, guards) run တယ်

  • Subscriber တွေကို state change ဖြစ်တိုင်း notify လုပ်တယ်

Event Processing လုပ်ပုံ

Machine ကို event ပို့တဲ့အခါ XState က အဆင့်ဆင့် လုပ်ပါတယ်:

  1. Valid transition ရှာတယ်: လက်ရှိ state ကနေ ဒီ event အတွက် ဘယ် transition လုပ်လို့ရလဲ check လုပ်တယ်

  2. Guard evaluate လုပ်တယ်: Guard condition ရှိရင် evaluate လုပ်ပြီး transition ခွင့်ပြုမလား check တယ်

  3. Exit action တွေ run တယ်: လက်ရှိ state ကနေ ထွက်တဲ့အခါ သတ်မှတ်ထားတဲ့ action တွေ run တယ်

  4. State update လုပ်တယ်: Internal state ကို အသစ် update လုပ်တယ်

  5. Entry action တွေ run တယ်: အသစ်ရောက်တဲ့ state အတွက် သတ်မှတ်ထားတဲ့ action တွေ run တယ်

  6. Subscriber တွေကို notify လုပ်တယ်: State change ကို စောင့်ကြည့်နေတဲ့ callback တွေကို trigger လုပ်တယ်

Vanilla JavaScript နဲ့ ရေးကြည့်မယ်

XState ဘယ်လို အလုပ်လုပ်လဲဆိုတာ သိအောင် အောက်က code တွေကို ကြည့်ရအောင်:

ဥပမာ - မီးပွိုင့် Machine

ဘာတွေဖြစ်နေလဲ

  1. Machine creation: createMachine() က configuration object ကို သိမ်းထားတယ်၊ ဘာမှ execute မလုပ်သေးဘူး

  2. Interpreter: interpret() က closure တစ်ခု create လုပ်တယ် - currentState, currentContext, listeners တွေကို track လုပ်ထားတယ်

  3. Event processing: send() ခေါ်တဲ့အခါ လက်ရှိ state က transition table ကို ကြည့်ပြီး event နဲ့ match တဲ့ transition ကို ရှာတယ်၊ exit action run တယ်၊ context update တယ်၊ entry action run တယ်၊ state update တယ်၊ subscriber တွေကို notify လုပ်တယ်

  4. Context: direct mutation မဖြစ်အောင် Spread operator နဲ့ copy လုပ်ထားတယ်၊

Transition Map

State machine အလုပ်လုပ်အောင်လုပ်တဲ့ အဓိက data structure က transition map ပါ။ သူက (current_state, event) → next_state ဆိုတဲ့ mapping ကို သိမ်းထားတာပါ။

ဇယားနဲ့ကြည့်ရအောင်

XState က literal table မသုံးပေမယ့် visualization အတွက် table ပုံစံနဲ့ ကြည့်လို့ရတယ်:

လက်ရှိ State / Event →
TIMER
EMERGENCY
RESET

green

yellow

red

green

yellow

red

red

green

red

green

red

green

ဒီ table က visualization လုပ်ဖို့ပဲ။ တကယ့် implementation က data structureနဲ့ မတူဘူး။

Implementation နည်း ၂ မျိုး

နည်း ၁: 2D Array သုံးတာ

2D array သုံးတာက မြန်ပေမယ့် ဖတ်ရခက်တယ်။

နည်း ၂: Nested Object (XState သုံးတဲ့ နည်း)

Nested object သုံးတာက ဖတ်ရလွယ်တယ်၊ flexible တယ်။

Comparison of Approaches

Aspect
2D Array
Nested Object (XState)

Data Structure

Array of arrays

Object of objects

Access Method

array[0][1]

config['green']['TIMER']

Lookup Speed

O(1) - direct indexing

O(1) - hash lookup

Readability

Poor - numeric indices

Excellent - named keys

Extensibility

Limited

High - can add metadata

Core Design Pattern တွေ

1. State Pattern

အဓိက pattern ပါ။ State Pattern က state-specific behavior တွေကို encapsulate လုပ်ပြီး လက်ရှိ state object ကို delegate လုပ်တာပါ။ XState က ဒါကို configuration-based လုပ်ထားတယ် - class တွေ ရေးစရာမလို configuration object တွေနဲ့ပဲ state define လုပ်လို့ရတယ်။

2. Interpreter Pattern

Machine definition က abstract syntax tree (AST) လိုမျိုးပါ - logic ကို represent လုပ်တဲ့ data structure တစ်ခု။ Actor/interpreter က runtime မှာ configuration ကို evaluate လုပ်တာပါ။

3. Finite State Machine Algorithm

State Transition Algorithm:

  1. currentState = initialState

  2. Event တွေ လက်ခံနေချိန်:

    • Transition ရှာတယ်: transitions[currentState][eventType]

    • Valid transition ရှိရင်:

      • Exit action run

      • State update

      • Entry action run

      • Context update (ရှိရင်)

    • မရှိရင် event ignore

    • Observer တွေကို notify

4. Observer Pattern

Subscription mechanism အတွက် Observer pattern သုံးတယ်:

5. Command Pattern

Action တွေက command တွေပါ - operation တွေကို encapsulate လုပ်ပြီး data အနေနဲ့ သိမ်းထားပြီး နောက်မှ execute လုပ်တာပါ:

Algorithm အချုပ်

ALGORITHM: Finite State Machine Transition

INPUT:

  • currentState: String

  • event: Object { type, payload }

  • machine: Configuration object

OUTPUT:

  • nextState: String

  • updatedContext: Object

STEPS:

  1. stateNode = machine.states[currentState]

  2. transition = stateNode.on[event.type] transition null ဆို currentState, context return (ပြောင်းမှာမဟုတ်)

  3. transition.guard ရှိရင်: guard false ဆို currentState, context return (guard က block လုပ်)

  4. stateNode.exit က action တွေ execute

  5. targetState = transition.target

  6. transition.actions က action တွေ execute: action.type == 'assign' ဆို context merge မဟုတ်ရင် action execute

  7. targetStateNode.entry က action တွေ execute

  8. Subscriber တွေကို notify({ state: targetState, context })

  9. targetState, context return

အရေးကြီးတဲ့ အချက်တွေ

Hierarchical States

XState က nested state တွေ (statechart တွေ) support လုပ်တယ်။ အတွင်းပိုင်းမှာ state value က simple state တွေအတွက် string ဖြစ်နိုင်တယ်၊ hierarchical state တွေအတွက် nested object ဖြစ်နိုင်တယ်။ Transition လုပ်တဲ့အခါ parent နဲ့ child state တွေကို အစဉ်လိုက် ဝင်/ထွက် handle လုပ်တယ်။

Context Management

Machine က context object (finite state တွေထက်ပိုတဲ့ data ကို သိမ်းတဲ့ extended state) ကို maintain လုပ်တယ်။ assign action တွေနဲ့ update လုပ်တယ်။ Immutable update pattern သုံးတယ် - transition တိုင်း state object အသစ် create လုပ်တယ်၊ original ကို mutate မလုပ်ဘူး။

XState ရဲ့ အားသာချက်: Implicit state ကို explicit လုပ်တယ်၊ impossible state တွေကို မဖြစ်နိုင်အောင် လုပ်တယ် - မဖြစ်သင့်တဲ့ state combination တွေမှာ မှားပြီးတော့ မရောက်နိုင်ဘူး။

ဘာကြောင့် ဒီ design ကောင်းလဲ

  • Declarative: State နဲ့ transition တွေကို describe လုပ်တာပဲ၊ control flow ရေးစရာမလို

  • Separation of concerns: State logic က business logic နဲ့ ခွဲထားတယ်

  • Predictable: Input တူရင် output တူတယ် (deterministic)

  • Testable: Guard နဲ့ action တွေက pure function တွေ

  • Visualizable: Configuration ကို state diagram အနေနဲ့ render လို့ရတယ်

နိဂုံး

Core pattern က State Pattern + Interpreter + Observer ပေါင်းတာပါ၊ state transition lookup mechanism နဲ့ အလုပ်လုပ်တာပါ။ Algorithm ကတော့ ရိုးရိုးပါပဲ - lookup structure တစ်ခုနဲ့ side effect တွေပါ။

တကယ့် XState က ပိုရှုပ်ပါတယ်၊ အောက်ကဟာတွေကို support လုပ်တယ်:

  • Guard တွေ (conditional transition)

  • Hierarchical နဲ့ parallel state တွေ (statechart)

  • History state တွေ

  • Child machine တွေ spawn လုပ်တဲ့ Actor model

  • TypeScript type safety အပြည့်အစုံ

  • Built-in testing utility တွေ

ဒါပေမယ့် အခုပြခဲ့တဲ့ fundamental pattern က XState ရဲ့ အလုပ်လုပ်ပုံ အကြမ်းဖျင်းမျှသာဖြစ်ပါတယ်။

Last updated