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 က အဆင့်ဆင့် လုပ်ပါတယ်:
Valid transition ရှာတယ်: လက်ရှိ state ကနေ ဒီ event အတွက် ဘယ် transition လုပ်လို့ရလဲ check လုပ်တယ်
Guard evaluate လုပ်တယ်: Guard condition ရှိရင် evaluate လုပ်ပြီး transition ခွင့်ပြုမလား check တယ်
Exit action တွေ run တယ်: လက်ရှိ state ကနေ ထွက်တဲ့အခါ သတ်မှတ်ထားတဲ့ action တွေ run တယ်
State update လုပ်တယ်: Internal state ကို အသစ် update လုပ်တယ်
Entry action တွေ run တယ်: အသစ်ရောက်တဲ့ state အတွက် သတ်မှတ်ထားတဲ့ action တွေ run တယ်
Subscriber တွေကို notify လုပ်တယ်: State change ကို စောင့်ကြည့်နေတဲ့ callback တွေကို trigger လုပ်တယ်
Vanilla JavaScript နဲ့ ရေးကြည့်မယ်
XState ဘယ်လို အလုပ်လုပ်လဲဆိုတာ သိအောင် အောက်က code တွေကို ကြည့်ရအောင်:
ဥပမာ - မီးပွိုင့် Machine
ဘာတွေဖြစ်နေလဲ
Machine creation:
createMachine()က configuration object ကို သိမ်းထားတယ်၊ ဘာမှ execute မလုပ်သေးဘူးInterpreter:
interpret()က closure တစ်ခု create လုပ်တယ် -currentState,currentContext,listenersတွေကို track လုပ်ထားတယ်Event processing:
send()ခေါ်တဲ့အခါ လက်ရှိ state က transition table ကို ကြည့်ပြီး event နဲ့ match တဲ့ transition ကို ရှာတယ်၊ exit action run တယ်၊ context update တယ်၊ entry action run တယ်၊ state update တယ်၊ subscriber တွေကို notify လုပ်တယ်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 ပုံစံနဲ့ ကြည့်လို့ရတယ်:
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
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:
currentState = initialState
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:
stateNode = machine.states[currentState]
transition = stateNode.on[event.type] transition null ဆို currentState, context return (ပြောင်းမှာမဟုတ်)
transition.guard ရှိရင်: guard false ဆို currentState, context return (guard က block လုပ်)
stateNode.exit က action တွေ execute
targetState = transition.target
transition.actions က action တွေ execute: action.type == 'assign' ဆို context merge မဟုတ်ရင် action execute
targetStateNode.entry က action တွေ execute
Subscriber တွေကို notify({ state: targetState, context })
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