# 通知設計書 13-ホットアップデート通知

## 概要

本ドキュメントは、Bun DevServerにおけるホットアップデート通知の設計を記載する。ファイル変更時にWebSocket経由でクライアントにホットアップデートを配信する機能である。

### 本通知の処理概要

ホットアップデート通知は、開発サーバーがファイルシステムの変更を検知した際に、接続中の全クライアントに対して変更内容を配信し、ページリロードなしでモジュールを更新させる機能である。

**業務上の目的・背景**：フロントエンド開発において、コード変更のたびにページをリロードすると、アプリケーションの状態が失われ、開発効率が低下する。HMR（Hot Module Reloading）により、変更されたモジュールのみを差し替えることで、状態を維持したまま即座に変更を反映できる。React Fast Refreshなどのフレームワーク機能と連携して動作する。

**通知の送信タイミング**：DevServerがファイルシステムウォッチャー（bun_watcher）経由でファイル変更を検知し、インクリメンタルバンドルが完了した後に発火する。バンドル処理の結果に基づいて、影響を受けるルートに接続しているクライアントにのみ通知が送信される。

**通知の受信者**：HMR WebSocket（`/_bun/hmr`）に接続している全クライアント、または特定のルートをアクティブに閲覧しているクライアント。クライアントはhmr-runtime-client.tsによって通知を処理する。

**通知内容の概要**：`hot_update`メッセージタイプで送信され、更新されたモジュールの情報、新しいバンドルコード、ルートバンドルインデックスなどを含む。クライアントはこの情報を元にモジュールを動的に置き換える。

**期待されるアクション**：クライアント側のHMRランタイムが更新されたモジュールを受け取り、既存のモジュールを新しいコードで置き換える。Reactコンポーネントの場合、Fast Refreshにより状態を維持したまま再レンダリングが行われる。

## 通知種別

アプリ内通知（WebSocket経由でのリアルタイム配信）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（Pub/Sub） |
| 優先度 | 高 |
| リトライ | なし（WebSocket Pub/Sub方式） |

### 送信先決定ロジック

1. 変更されたファイルに関連するルートを特定
2. そのルートを`active_route`として設定しているHmrSocket接続を特定
3. 該当するクライアントに対してのみメッセージを配信（uWS Pub/Sub機能を使用）

## 通知テンプレート

### WebSocket通知の場合

| 項目 | 内容 |
|-----|------|
| プロトコル | WebSocket (Binary) |
| メッセージID | `hot_update` (MessageId列挙型) |
| 配信方式 | uWS Pub/Subトピックベース |

### メッセージ構造

```
[1バイト: MessageId.hot_update]
[4バイト: ルートバンドルインデックス (u32)]
[可変長: 更新データペイロード]
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| route_bundle_index | 更新対象ルートの識別子 | DevServer.route_bundles | Yes |
| generation | バンドル世代番号 | RouteBundle.client_script_generation | Yes |
| module_updates | 更新モジュール情報 | IncrementalResult | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ファイル変更 | bun_watcher検知 | バンドル成功 | ソースファイルの保存時 |
| CSS変更 | CSSファイル変更 | CSS HMR有効 | スタイルシートの変更時 |
| 依存関係変更 | インポート追加/削除 | 影響範囲あり | モジュールグラフの変更時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| バンドルエラー | ビルドエラーが発生した場合は更新通知ではなくエラー通知を送信 |
| クライアント未接続 | 対象ルートにアクティブなクライアントがいない場合 |
| 致命的エラー | hasFatalErrorフラグが設定されている場合はページリロードが必要 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ファイル変更検知] --> B[bun_watcher通知]
    B --> C[変更ファイルを特定]
    C --> D[インクリメンタルバンドル実行]
    D --> E{バンドル成功?}
    E -->|No| F[エラー通知送信]
    E -->|Yes| G[影響を受けるルートを特定]
    G --> H[IncrementalResult構築]
    H --> I[hot_updateメッセージ作成]
    I --> J[Pub/Subで対象クライアントに配信]
    J --> K[クライアントがモジュール更新]
    K --> L[処理終了]
    F --> L
```

## データベース参照・更新仕様

### 参照テーブル一覧

本通知はデータベースを使用しない。インメモリのグラフ構造から情報を取得する。

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| DevServer.client_graph | クライアント側モジュールグラフ | IncrementalGraph(.client) |
| DevServer.server_graph | サーバー側モジュールグラフ | IncrementalGraph(.server) |
| DevServer.route_bundles | ルートバンドル情報 | ArrayListUnmanaged(RouteBundle) |
| DevServer.incremental_result | バンドル結果 | IncrementalResult |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| バンドルエラー | パース/解決エラー | エラー通知を送信、bundling_failuresに記録 |
| WebSocket切断 | クライアント離脱 | 自動クリーンアップ |
| バージョン不一致 | configurationハッシュ不一致 | ハードリロード要求 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（Pub/Sub方式のためリトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（ファイル変更に応じて配信） |
| 1日あたり上限 | なし |

### 配信時間帯

開発サーバー稼働中は常時配信可能

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

- ローカル開発環境での使用を想定
- 本番環境ではDevServerを使用しないこと
- ソースコードがクライアントに配信されるため、機密コードの取り扱いに注意

## 備考

- React Fast Refreshと連携して、コンポーネントの状態を維持したまま更新が可能
- CSS変更は専用のeditCssArray/editCssContent関数で処理される
- configuration_hash_keyによりバージョン管理を行い、不一致時はハードリロードを実行

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DevServer.zig | `src/bake/DevServer.zig` | MessageId列挙型のhot_update定義 |
| 1-2 | HotReloadEvent.zig | `src/bake/DevServer/HotReloadEvent.zig` | ホットリロードイベントの構造 |
| 1-3 | RouteBundle.zig | `src/bake/DevServer/RouteBundle.zig` | ルートバンドルの状態管理 |

**読解のコツ**: IncrementalGraph構造体がモジュール依存関係を管理しており、変更の影響範囲を計算する中核となる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DevServer.zig | `src/bake/DevServer.zig` | WatcherAtomicsとファイル変更検知 |
| 2-2 | DevServer.zig | `src/bake/DevServer.zig` | startAsyncBundleメソッド |

**主要処理フロー**:
1. bun_watcherがファイル変更を検知
2. WatcherAtomicsを通じてDevServerに通知
3. startAsyncBundleでインクリメンタルバンドル実行
4. publishメソッドでクライアントに配信

#### Step 3: Pub/Sub配信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HmrSocket.zig | `src/bake/DevServer/HmrSocket.zig` | subscribeメソッドでのトピック購読 |
| 3-2 | DevServer.zig | `src/bake/DevServer.zig` | publishメソッドでのメッセージ配信 |

**主要処理フロー**:
- クライアントがset_urlでアクティブルートを設定
- DevServerがactive_viewersをカウント
- 変更時に該当トピックにpublish

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

```
bun_watcher (ファイルシステム監視)
    │
    ├─ WatcherAtomics.processEvents()
    │      │
    │      └─ DevServer.handleWatchEvent()
    │             │
    │             ├─ 変更ファイルをIncrementalGraphに反映
    │             │
    │             └─ startAsyncBundle()
    │                    │
    │                    ├─ BundleV2実行
    │                    │
    │                    └─ finalizeBundle()
    │                           │
    │                           ├─ IncrementalResult構築
    │                           │
    │                           └─ publish(.hot_update, payload)
    │                                  │
    │                                  └─ uWS Pub/Sub配信
    │
    └─ HmrSocket (クライアント)
           │
           └─ hmr-runtime-client.ts
                  │
                  └─ モジュール差し替え / React Fast Refresh
```

### データフロー図

```
[入力]                    [処理]                           [出力]

ファイル変更 ───▶ bun_watcher ───▶ DevServer ───▶ Pub/Sub ───▶ HmrSocket
    │                   │              │              │           │
    │                   │              │              │           │
    └─ .ts/.tsx/.js     └─ 変更通知    └─ バンドル    └─ hot_update └─ モジュール
                                           │              メッセージ     更新
                                           │
                                           └─ IncrementalResult
                                                  ├─ 更新モジュール
                                                  └─ 影響ルート
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DevServer.zig | `src/bake/DevServer.zig` | ソース | DevServerメイン実装、バンドル管理 |
| HmrSocket.zig | `src/bake/DevServer/HmrSocket.zig` | ソース | WebSocket接続管理、トピック購読 |
| HotReloadEvent.zig | `src/bake/DevServer/HotReloadEvent.zig` | ソース | ホットリロードイベント定義 |
| RouteBundle.zig | `src/bake/DevServer/RouteBundle.zig` | ソース | ルートバンドル状態管理 |
| hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | ソース | クライアント側HMRランタイム |
| IncrementalGraph.zig | `src/bake/DevServer/IncrementalGraph.zig` | ソース | モジュール依存グラフ管理 |
