# 機能設計書 109-DevServer

## 概要

本ドキュメントは、BunにおけるDevServer機能の機能設計を記述したものである。DevServerは、Bakeフレームワークの開発サーバー実装であり、バンドラー、ルーティング、ホットモジュールリプレースメントを制御する。

### 本機能の処理概要

DevServerは`Bun.serve`のインスタンスにアタッチされ、完全なインクリメンタル追跡によりファイルの再処理を最小限に抑える。ファイル内容の編集（インポートの調整を除く）は、常にそのファイルのみを再バンドルする必要がある。

**業務上の目的・背景**：開発時のイテレーション速度は生産性に直結する。DevServerは、変更されていないファイルの再処理を禁止し、完全なインクリメンタル追跡により、ファイル編集時に最小限のバンドルのみを実行する。

**機能の利用シーン**：
- 開発時のホットリロード
- サーバーサイドレンダリングのリアルタイムプレビュー
- クライアントコードの即座更新
- エラーオーバーレイの表示

**主要な処理内容**：
1. `DevServer.init()`: 開発サーバーの初期化
2. `IncrementalGraph`: クライアント/サーバーのインクリメンタルグラフ管理
3. `RouteBundle`: ルートごとのバンドル状態管理
4. `HmrSocket`: WebSocketによるHMR通信
5. `WatcherAtomics`: ファイル監視とイベント処理

**関連システム・外部連携**：
- `Bun.serve`: HTTPサーバー統合
- `Bun.Watcher`: ファイルシステム監視
- WebSocket: HMRクライアント通信
- `BundleV2`: バンドラー

**権限による制御**：
- `is_from_localhost`: ローカルホストからの接続のみ機密操作を許可

## 関連画面

本機能はバックエンドモジュールであり、直接的な関連画面は存在しない。ただし、エラーオーバーレイをブラウザに表示する。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エラーオーバーレイ | 出力 | バンドル/評価エラー表示 |

## 機能種別

開発サーバー / ホットモジュールリプレースメント

## 入力仕様

### 入力パラメータ

#### `DevServer.Options`

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| arena | Allocator | Yes | アロケータ（DevServer.deinit()まで生存） | - |
| root | [:0]const u8 | Yes | プロジェクトルートディレクトリ | 絶対パス |
| vm | *VirtualMachine | Yes | JavaScript仮想マシン | - |
| framework | bake.Framework | Yes | フレームワーク設定 | - |
| bundler_options | bake.SplitBundlerOptions | Yes | バンドラーオプション | - |
| broadcast_console_log_from_browser_to_server | bool | Yes | ブラウザコンソールログのブロードキャスト | - |
| dump_sources | ?[]const u8 | No | デバッグ用ソースダンプディレクトリ | - |
| dump_state_on_crash | ?bool | No | クラッシュ時の状態ダンプ | - |

#### HMR WebSocketメッセージ（インカミング）

| メッセージID | 説明 | ペイロード |
|-------------|------|----------|
| init | 初期化、ソースマップ参照登録 | generation (8 hex chars) |
| subscribe | トピック購読 | topic chars |
| set_url | アクティブルート設定 | URL pattern |
| testing_batch_events | テストバッチイベント | - |

### 入力データソース

- HTTPリクエスト
- WebSocketメッセージ
- ファイルシステム変更イベント

## 出力仕様

### 出力データ

#### HMR WebSocketメッセージ（アウトゴーイング）

| メッセージID | 説明 | ペイロード |
|-------------|------|----------|
| version | サーバーバージョン/設定ハッシュ | configuration_hash_key (16 chars) |
| hot_update | ホットアップデート通知 | 更新情報 |
| full_reload | 完全リロード要求 | - |
| set_url_response | URL設定応答 | RouteBundle.Index |

#### RouteBundle.State

| 状態 | 説明 |
|------|------|
| unqueued | 未ビルド（遅延ビルド） |
| bundling | バンドル中 |
| deferred_to_next_bundle | 次回バンドルで処理予定 |
| possible_bundling_failures | バンドル失敗の可能性 |
| evaluation_failure | モジュール評価失敗 |
| loaded | ロード完了 |

### 出力先

- WebSocket（HMR通知）
- HTTPレスポンス（バンドル済みコード）
- コンソール（デバッグログ）

## 処理フロー

### 処理シーケンス（初期化）

```
1. DevServer構造体初期化
   └─ bun.new(DevServer, options)
2. ファイルシステム初期化
   └─ bun.fs.FileSystem.init(root)
3. Watcher初期化
   └─ Watcher.init() + start()
4. トランスパイラー初期化
   └─ framework.initTranspiler() × 3 (server/client/ssr)
5. フレームワーク解決
   └─ framework.resolve()
6. ルーター初期化
   └─ FrameworkRouter.initEmpty()
7. 初期ルートスキャン
   └─ scanInitialRoutes()
```

### 処理シーケンス（リクエスト処理）

```
1. リクエスト受信
   └─ HTTPハンドラー
2. ルートマッチング
   └─ router.matchSlow(path)
3. RouteBundleルックアップ
   └─ route_bundles[route.bundle]
4. バンドル状態確認
   ├─ loaded: 即座にレスポンス
   ├─ unqueued: バンドルをキュー
   └─ bundling: 完了を待機
5. レスポンス生成
   └─ サーバーサイドレンダリング or 静的配信
```

### 処理シーケンス（ホットリロード）

```
1. ファイル変更検出
   └─ bun_watcher.onFileUpdate()
2. 変更ファイル特定
   └─ watcher_atomics.processEvents()
3. インクリメンタルグラフ更新
   └─ client_graph/server_graph 更新
4. 影響範囲計算
   └─ 依存関係を辿って影響ルートを特定
5. 再バンドル
   └─ BundleV2で差分バンドル
6. HMR通知
   └─ WebSocketで接続クライアントに通知
```

### フローチャート

```mermaid
flowchart TD
    A[DevServer.init] --> B[Watcher起動]
    B --> C[トランスパイラー初期化]
    C --> D[ルーター初期化]
    D --> E[HTTPサーバー待機]

    E --> F{イベント種別}

    F -->|HTTPリクエスト| G[ルートマッチング]
    G --> H{バンドル状態?}
    H -->|loaded| I[レスポンス返却]
    H -->|unqueued| J[バンドルキュー]
    H -->|bundling| K[完了待機]
    J --> L[BundleV2実行]
    L --> I
    K --> I

    F -->|ファイル変更| M[変更検出]
    M --> N[インクリメンタルグラフ更新]
    N --> O[影響範囲計算]
    O --> P[差分バンドル]
    P --> Q[HMR通知]
    Q --> E

    F -->|WebSocket| R[HmrSocket処理]
    R --> S{メッセージ種別}
    S -->|init| T[ソースマップ参照登録]
    S -->|set_url| U[アクティブルート設定]
    S -->|subscribe| V[トピック購読]
    T --> E
    U --> E
    V --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-901 | インクリメンタルビルド | 変更ファイルのみ再バンドル | ファイル変更時 |
| BR-902 | 遅延バンドル | ルートは要求時に初めてバンドル | 初回リクエスト時 |
| BR-903 | 設定ハッシュ | フレームワーク設定変更時に完全リロード | configuration_hash_key不一致 |
| BR-904 | クライアントコンポーネント境界 | use clientで依存追跡を停止 | サーバーコンポーネント使用時 |
| BR-905 | ローカルホスト制限 | 機密操作はローカルホストのみ | WebSocket操作時 |

### 計算ロジック

**configuration_hash_key計算**：
- Bunバイナリのmtime（デバッグ）またはgit_sha_short（リリース）
- HMRランタイムコード
- 全FileSystemRouterType設定
- サーバーコンポーネント設定
- React Fast Refresh設定
- 組み込みモジュール

**インクリメンタル影響範囲**：
- 変更ファイルから逆方向に依存関係を辿る
- `is_client_component_boundary`で追跡を停止
- `is_route`でルート境界を検出

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーケース | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Framework missing files | Error | 必須ファイルが見つからない | Reactインストールコマンドを表示 |
| Bundling failure | SerializedFailure | バンドル中のエラー | エラーオーバーレイ表示 |
| Evaluation failure | Error | モジュール評価時エラー | エラーオーバーレイ表示 |
| Route collision | Error | 同一パターンの重複ルート | ファイル名変更を促す |

### リトライ仕様

- ファイル変更で自動的に再ビルド試行
- エラー状態は次回ビルド成功まで保持

## トランザクション仕様

本機能はトランザクションを使用しない。

## パフォーマンス要件

- インクリメンタルビルド: 1ファイル変更で1ファイルのみ再バンドル
- メモリ効率: PackedMapで構造体をパック化
- 遅延評価: ルートは要求されるまでバンドルしない

## セキュリティ考慮事項

- `is_from_localhost`でローカルホスト接続を判定
- 機密操作（状態ダンプ等）はローカルホストのみ
- ソースマップは参照カウントで管理

## 備考

- DevServerは実験的機能であり、APIは変更される可能性がある
- `frontend_only`モード: ルーターなしでフロントエンドのみバンドル
- `assume_perfect_incremental_bundling`: デバッグ用フラグ

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: DevServerのエントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DevServer.zig | `src/bake/DevServer.zig` | メイン構造体と初期化 |

**読解のコツ**:
- **1-9行目**: DevServerの目的説明（インクリメンタル追跡）
- **17-29行目**: `Options`構造体で初期化オプションを定義
- **37-156行目**: DevServer構造体のフィールド定義
- **248-260行目**: 内部URLプレフィックス（`/_bun`）
- **287-558行目**: `init`関数で初期化処理
- **561-699行目**: `deinit`関数でリソース解放

#### Step 2: RouteBundleを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RouteBundle.zig | `src/bake/DevServer/RouteBundle.zig` | ルートバンドル状態管理 |

**主要処理フロー**:
1. **5-12行目**: `server_state`と`data`（framework/html）の定義
2. **27-43行目**: `Framework`構造体でフルスタックルート情報
3. **45-62行目**: `HTML`構造体でフロントエンドルート情報
4. **66-88行目**: `State`列挙型でバンドル状態を定義
5. **121-135行目**: `invalidateClientBundle`でキャッシュ無効化

#### Step 3: IncrementalGraphを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IncrementalGraph.zig | `src/bake/DevServer/IncrementalGraph.zig` | インクリメンタルグラフ |

**主要処理フロー**:
- **7-44行目**: `ServerFile`構造体（RSC/SSR/クライアントコンポーネントフラグ）
- **46-70行目**: `Content`共用体（JS/CSS/アセット）
- **72-170行目**: `ClientFile`構造体とパック化

#### Step 4: HmrSocketを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HmrSocket.zig | `src/bake/DevServer/HmrSocket.zig` | HMR WebSocket通信 |

**主要処理フロー**:
- **3-12行目**: HmrSocket構造体のフィールド
- **14-28行目**: `new`でソケット作成
- **30-41行目**: `onOpen`でバージョン送信
- **43-150行目**: `onMessage`でメッセージ処理

### プログラム呼び出し階層図

```
[Bun.serve]
    │
    └─ DevServer.init(options)
           │
           ├─ FileSystem.init(root)
           ├─ Watcher.init() + start()
           │      └─ onFileUpdate() ─────────────────┐
           │                                          │
           ├─ framework.initTranspiler() × 3          │
           │      ├─ server_transpiler                │
           │      ├─ client_transpiler                │
           │      └─ ssr_transpiler                   │
           │                                          │
           ├─ FrameworkRouter.initEmpty()             │
           │      └─ scanInitialRoutes()              │
           │                                          │
           └─ [HTTPリクエスト処理]                    │
                  │                                   │
                  ├─ router.matchSlow(path)           │
                  │      └─ RouteBundle取得           │
                  │                                   │
                  ├─ [バンドル状態に応じて]           │
                  │      ├─ loaded: 即座返却          │
                  │      ├─ unqueued: キュー追加      │
                  │      └─ bundling: 待機            │
                  │                                   │
                  └─ BundleV2.bundle() ◀──────────────┘
                         │                   （ファイル変更）
                         ├─ client_graph更新
                         ├─ server_graph更新
                         └─ HMR通知
                                │
                                ▼
                         [WebSocket送信]
                                │
                                └─ HmrSocket.onMessage()
```

### データフロー図

```
[ファイルシステム]              [DevServer]                    [ブラウザ]
     │                              │                              │
     │  ファイル変更                │                              │
     ├──────────────────────▶ bun_watcher                         │
     │                              │                              │
     │                       watcher_atomics                       │
     │                              │                              │
     │                       ┌──────┴──────┐                       │
     │                       ▼             ▼                       │
     │               client_graph    server_graph                  │
     │                       │             │                       │
     │                       └──────┬──────┘                       │
     │                              │                              │
     │                       incremental_result                    │
     │                              │                              │
     │                       BundleV2                              │
     │                              │                              │
     │                       route_bundles                         │
     │                              │                              │
     │                              │  hot_update                  │
     │                              ├──────────────────────────────▶
     │                              │                              │
     │                              │  HTTPレスポンス              │
     │                              ├◀─────────────────────────────┤
     │                              │                              │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DevServer.zig | `src/bake/DevServer.zig` | ソース | メイン構造体 |
| RouteBundle.zig | `src/bake/DevServer/RouteBundle.zig` | ソース | ルートバンドル管理 |
| IncrementalGraph.zig | `src/bake/DevServer/IncrementalGraph.zig` | ソース | インクリメンタルグラフ |
| HmrSocket.zig | `src/bake/DevServer/HmrSocket.zig` | ソース | HMR WebSocket |
| Assets.zig | `src/bake/DevServer/Assets.zig` | ソース | アセット管理 |
| SourceMapStore.zig | `src/bake/DevServer/SourceMapStore.zig` | ソース | ソースマップ管理 |
| DirectoryWatchStore.zig | `src/bake/DevServer/DirectoryWatchStore.zig` | ソース | ディレクトリ監視 |
| WatcherAtomics.zig | `src/bake/DevServer/WatcherAtomics.zig` | ソース | 監視アトミック操作 |
| HotReloadEvent.zig | `src/bake/DevServer/HotReloadEvent.zig` | ソース | ホットリロードイベント |
| SerializedFailure.zig | `src/bake/DevServer/SerializedFailure.zig` | ソース | 失敗シリアライズ |
| hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | ソース | クライアントHMRランタイム |
| hmr-runtime-server.ts | `src/bake/hmr-runtime-server.ts` | ソース | サーバーHMRランタイム |
