# 通知設計書 4-サーバーサイドコード変更通知

## 概要

本ドキュメントは、Bun の Hot Module Reloading (HMR) 機能において、サーバーサイドのコードが変更された際にブラウザのコンソールに表示されるリロード通知の設計を記載する。

### 本通知の処理概要

この通知は、サーバーサイドのコード（ルートハンドラやサーバーコンポーネントなど）が変更され、その変更を反映するためにリロードが必要であることを開発者に知らせる。通常のクライアントサイド HMR とは異なり、サーバーサイドの変更はページのリロードが必要となる場合がある。

**業務上の目的・背景**：サーバーサイドレンダリング（SSR）やサーバーコンポーネントを使用するアプリケーションでは、サーバーサイドのコード変更はクライアントサイドの HMR だけでは反映できない。この通知により、開発者はサーバーサイドの変更が検出され、適切なリロード処理が行われることを把握できる。フレームワークが `onServerSideReload` コールバックを実装している場合はソフトリロードが試行され、実装されていない場合はハードリロード（ページ全体の再読み込み）が実行される。

**通知の送信タイミング**：WebSocket 経由で `hot_update` メッセージを受信し、そのメッセージにサーバーサイドルートの更新が含まれており、かつ現在表示中のルートが更新対象に含まれている場合に送信される。

**通知の受信者**：ブラウザのコンソールを通じて開発者に通知される。`console.info()` メソッドで情報レベルとして出力される。

**通知内容の概要**：`[Bun] Server-side code changed, reloading!` という固定メッセージがコンソールに出力される。このメッセージは、サーバーサイドのコードが変更され、リロード処理が開始されることを示す。

**期待されるアクション**：開発者はこのメッセージを確認した後、ページが自動的にリロードされることを待つ。リロードが失敗した場合はエラーメッセージがコンソールに表示され、手動でのハードリロードが必要になる可能性がある。

## 通知種別

コンソール通知（ブラウザ開発者ツール）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（hot_update メッセージ処理中に実行、リロード処理は非同期で実行） |
| 優先度 | 中（リロードを伴う重要な通知） |
| リトライ | 無（コンソール出力は失敗しない。リロード失敗時はハードリロードにフォールバック） |

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

ブラウザの `console.info()` メソッドを使用してコンソールに直接出力するため、特別な送信先決定ロジックは存在しない。

## 通知テンプレート

### コンソール出力

| 項目 | 内容 |
|-----|------|
| 出力レベル | info |
| プレフィックス | `[Bun]` |

### 本文テンプレート

```
[Bun] Server-side code changed, reloading!
```

### 添付ファイル

該当なし（コンソール出力のため）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定メッセージのため変数なし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| WebSocket メッセージ | `MessageId.hot_update` | `isServerSideRouteUpdate === true` | サーバーサイドルートの更新が検出されたとき |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| クライアントサイドのみの変更 | サーバーサイドルートの更新が含まれていない場合 |
| 現在のルートが更新対象外 | `currentRouteIndex` が `serverSideRoutesUpdated` に含まれていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[hot_update メッセージ受信] --> B[サーバーサイドルート更新リスト解析]
    B --> C[現在ルートの更新チェック]
    C --> D{現在ルートが更新対象?}
    D -->|No| E[CSS/JS の HMR 処理]
    D -->|Yes| F[isServerSideRouteUpdate = true]
    F --> G{hasFatalError かつ更新あり?}
    G -->|Yes| H[fullReload 実行]
    G -->|No| I[console.info でメッセージ出力]
    I --> J{onServerSideReload 実装あり?}
    J -->|Yes| K[onServerSideReload 実行]
    J -->|No| L[fullReload 実行]
    K --> M{リロード成功?}
    M -->|Yes| N[終了]
    M -->|No| O[エラーログ出力]
    O --> L
    H --> N
    L --> N
    E --> N
```

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

### 参照テーブル一覧

該当なし（クライアントサイドのコンソール出力のため、データベースアクセスは発生しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| onServerSideReload 失敗 | フレームワークのリロードコールバックがエラーをスロー | エラーをコンソールに出力し、fullReload にフォールバック |
| リロード中の重複呼び出し | リロード処理中に再度変更が検出された場合 | `shouldPerformAnotherRouteReload` フラグで次回リロードをスケジュール |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 該当なし（失敗時は fullReload にフォールバック） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ファイル変更ごとに発生） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（開発時に随時発生）

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

- この通知は開発環境でのみ使用されることを想定している
- 機密情報は含まれない（固定メッセージのみ）
- サーバーサイドのコード変更情報はメッセージに含まれない

## 備考

- `onServerSideReload` はフレームワーク（React Server Components など）によって実装される
- `isPerformingRouteReload` フラグにより、リロード中の重複実行が防止される
- `hasFatalError` が true の場合（以前に致命的エラーが発生している場合）、即座に fullReload が実行される
- `fullReload()` は `location.reload()` を呼び出してページ全体を再読み込みする

---

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

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

### 推奨読解順序

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

サーバーサイドリロードに関連する状態変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 33-35行目の状態変数（`isPerformingRouteReload`, `shouldPerformAnotherRouteReload`, `currentRouteIndex`）を理解する |
| 1-2 | hmr-module.ts | `src/bake/hmr-module.ts` | `onServerSideReload` コールバックの型定義を理解する |

**読解のコツ**: `currentRouteIndex` はサーバーから `set_url_response` メッセージで設定される。この値を使ってどのルートが現在表示されているかを追跡している。

#### Step 2: メッセージハンドラを理解する

hot_update メッセージの処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 118-196行目の `handlers[MessageId.hot_update]` でメッセージ処理を理解する |
| 2-2 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 125-130行目でサーバーサイドルート更新リスト（List 1）を解析 |
| 2-3 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 132-160行目で現在ルートの更新確認（List 2）を理解 |

**主要処理フロー**:
1. **125-130行目**: サーバーサイドルート更新リストの解析
2. **136-137行目**: 現在ルートが更新対象かどうかの判定
3. **170-177行目**: `hasFatalError` チェックと `performRouteReload` 呼び出し

#### Step 3: リロード処理の詳細を理解する

`performRouteReload` 関数の処理を詳細に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | 37-63行目の `performRouteReload` 関数で通知出力とリロード処理を理解する |

**主要処理フロー**:
- **38行目**: `console.info("[Bun] Server-side code changed, reloading!");` でメッセージ出力
- **39-42行目**: リロード中の重複呼び出し防止
- **44-58行目**: `onServerSideReload` 実装がある場合の処理
- **62行目**: フォールバックとしての `fullReload()` 呼び出し

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

```
handlers[MessageId.hot_update]
    │
    ├─ DataViewReader で List 1 解析
    │      └─ serverSideRoutesUpdated Set 構築
    │
    ├─ List 2 解析（現在ルートの更新確認）
    │      └─ isServerSideRouteUpdate 判定
    │
    ├─ hasFatalError チェック
    │      └─ true の場合 → fullReload()
    │
    └─ performRouteReload()
           │
           ├─ console.info() ← 通知出力
           │
           ├─ isPerformingRouteReload チェック
           │      └─ true の場合 → shouldPerformAnotherRouteReload = true
           │
           ├─ onServerSideReload?.()
           │      │
           │      ├─ 成功 → 終了
           │      │
           │      └─ 失敗 → console.error() + fullReload()
           │
           └─ onServerSideReload 未実装 → fullReload()
```

### データフロー図

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

WebSocket               hot_update ハンドラ
hot_update ─────────▶      │
メッセージ                  ▼
                    サーバーサイドルート
                    更新リスト解析
                           │
                           ▼
                    現在ルート更新判定
                           │
                    ┌──────┴──────┐
                    ▼              ▼
              [更新あり]      [更新なし]
                    │              │
                    ▼              ▼
            performRouteReload  CSS/JS HMR
                    │
                    ▼
            console.info() ────────────────▶ [Bun] Server-side code...
                    │
                    ▼
            onServerSideReload / fullReload
                    │
                    ▼
              [ページリロード]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | ソース | HMR クライアントのエントリーポイント、hot_update ハンドラ |
| hmr-module.ts | `src/bake/hmr-module.ts` | ソース | `fullReload`, `onServerSideReload` の定義 |
| data-view.ts | `src/bake/client/data-view.ts` | ソース | `DataViewReader` クラス（バイナリメッセージ解析） |
| overlay.ts | `src/bake/client/overlay.ts` | ソース | `hasFatalError` フラグの管理 |
| DevServer.zig | `src/bake/DevServer.zig` | ソース | サーバーサイドの hot_update メッセージ生成 |
