> For the complete documentation index, see [llms.txt](https://channyeintun.gitbook.io/blogs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://channyeintun.gitbook.io/blogs/javascript/xstate-under-the-hood.md).

# 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 တွေကို ကြည့်ရအောင်:

```javascript
// State machine ရေးနည်း
function createMachine(config) {
  return {
    initialState: config.initial,
    states: config.states,
    context: config.context || {}
  };
}

function interpret(machine) {
  let currentState = machine.initialState;
  let currentContext = { ...machine.context };
  const listeners = [];

  function transition(event) {
    const stateConfig = machine.states[currentState];
    const transitions = stateConfig.on || {};
    const eventTransition = transitions[event.type];

    if (!eventTransition) {
      return currentState;
    }

    // Target state ယူ
    const targetState = typeof eventTransition === 'string' 
      ? eventTransition 
      : eventTransition.target;

    // Exit action တွေ run
    if (stateConfig.exit) {
      stateConfig.exit.forEach(action => action(currentContext, event));
    }

    // Context update
    if (eventTransition.actions) {
      eventTransition.actions.forEach(action => {
        if (action.type === 'assign') {
          Object.assign(currentContext, action.assignment(currentContext, event));
        }
      });
    }

    // Entry action တွေ run
    const nextStateConfig = machine.states[targetState];
    if (nextStateConfig.entry) {
      nextStateConfig.entry.forEach(action => action(currentContext, event));
    }

    // State update
    currentState = targetState;

    // Listener တွေကို notify
    listeners.forEach(listener => {
      listener({ state: currentState, context: currentContext });
    });

    return currentState;
  }

  return {
    start() {
      return this;
    },
    send(event) {
      const eventObj = typeof event === 'string' ? { type: event } : event;
      transition(eventObj);
    },
    getState() {
      return { value: currentState, context: currentContext };
    },
    subscribe(listener) {
      listeners.push(listener);
      return () => {
        const index = listeners.indexOf(listener);
        if (index > -1) listeners.splice(index, 1);
      };
    }
  };
}
```

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

```javascript
// မီးပွိုင့် machine တစ်ခု define လုပ်မယ်
const trafficLightMachine = createMachine({
  initial: 'green',
  context: {
    crossings: 0
  },
  states: {
    green: {
      entry: [() => console.log('🟢 အစိမ်း - သွားလို့ရ!')],
      on: {
        TIMER: 'yellow'
      },
      exit: [() => console.log('အစိမ်းကနေ ထွက်နေပြီ...')]
    },
    yellow: {
      entry: [() => console.log('🟡 အဝါ - သတိထား!')],
      on: {
        TIMER: 'red'
      }
    },
    red: {
      entry: [(context) => console.log('🔴 အနီ - ရပ်!')],
      on: {
        TIMER: {
          target: 'green',
          actions: [{
            type: 'assign',
            assignment: (context) => ({ 
              crossings: context.crossings + 1
            })
          }]
        }
      }
    }
  }
});

// Machine သုံးကြည့်မယ်
const service = interpret(trafficLightMachine).start();

// State change တိုင်း log ထုတ်မယ်
service.subscribe((state) => {
  console.log('လက်ရှိ state:', state);
});

// Event ပို့ကြည့်မယ်
service.send('TIMER'); // green -> yellow
service.send('TIMER'); // yellow -> red
service.send('TIMER'); // red -> green (crossings တိုးတယ်)
```

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

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 လုပ်ထားတယ်၊&#x20;

### 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 သုံးတာ**

```javascript
// State တွေကို index လုပ်
const GREEN = 0, YELLOW = 1, RED = 2;
const TIMER = 0, EMERGENCY = 1, RESET = 2;

// 2D array: array[state][event] = nextState
const transitions = [
  // [TIMER,  EMERGENCY, RESET]
  [YELLOW,    RED,       GREEN],  // GREEN state
  [RED,       RED,       GREEN],  // YELLOW state
  [GREEN,     RED,       GREEN]   // RED state
];

// Array indexing နဲ့ ရှာတယ်
const nextState = transitions[GREEN][TIMER]; // YELLOW
```

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

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

```javascript
// Nested object (hash map of hash maps)
const stateConfig = {
  green: {
    on: {
      TIMER: 'yellow',
      EMERGENCY: 'red',
      RESET: 'green'
    }
  },
  yellow: {
    on: {
      TIMER: 'red',
      EMERGENCY: 'red',
      RESET: 'green'
    }
  },
  red: {
    on: {
      TIMER: 'green',
      EMERGENCY: 'red',
      RESET: 'green'
    }
  }
};

// String key နဲ့ access လုပ်တယ်
const nextState = stateConfig['green'].on['TIMER']; // 'yellow'
```

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 သုံးတယ်:

```javascript
const listeners = [];

function subscribe(callback) {
  listeners.push(callback);
  return () => listeners.splice(listeners.indexOf(callback), 1);
}

function notify(state) {
  listeners.forEach(listener => listener(state));
}
```

#### 5. Command Pattern

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

```javascript
const actions = {
  increment: (context) => ({ count: context.count + 1 }),
  log: () => console.log('Action run ပြီ')
};

transition.actions.forEach(action => action(context));
```

### 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 ရှိရင်:\
   &#x20; guard false ဆို currentState, context return (guard က block လုပ်)
4. stateNode.exit က action တွေ execute
5. targetState = transition.target
6. transition.actions က action တွေ execute:\
   &#x20; action.type == 'assign' ဆို context merge\
   &#x20; မဟုတ်ရင် 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 ရဲ့ အလုပ်လုပ်ပုံ အကြမ်းဖျင်းမျှသာဖြစ်ပါတယ်။

<br>
