# 画面設計書 10-Hot Reload Sample

## 概要

本ドキュメントは、.NET WebAssembly のホットリロードサンプル画面「Hot Reload Sample」の設計内容を記載した画面設計書です。本画面は .NET Runtime リポジトリにおける WebAssembly のホットリロード（実行時コード更新）機能をデモンストレーションするサンプルアプリケーションです。

### 本画面の処理概要

本画面は、ブラウザ上で .NET WebAssembly ランタイムのホットリロード機能を使用して、アプリケーション実行中にコードを動的に更新し、結果の変化を確認するサンプルアプリケーションです。「Update」ボタンをクリックするたびに、`TestMeaning()` メソッドの返り値が変化します（42 -> 43 -> 128）。

**業務上の目的・背景**：本画面は、.NET WebAssembly のホットリロード（Edit and Continue / Metadata Update）機能を検証・デモンストレーションするために作成されました。ホットリロードは開発中のコード変更を即座に反映できる機能で、開発効率を大幅に向上させます。本サンプルでは、事前に準備されたデルタ（差分）ファイルを適用することで、実行時にメソッドの動作を変更しています。

**画面へのアクセス方法**：ローカル開発サーバー（通常は `http://localhost:8000/`）にブラウザでアクセスすることで画面を表示できます。環境変数 `DOTNET_MODIFIABLE_ASSEMBLIES=debug` の設定が必要です。

**主要な操作・処理内容**：
1. 画面ロード時に JavaScript（main.js）が .NET WebAssembly ランタイムを初期化
2. 環境変数 `DOTNET_MODIFIABLE_ASSEMBLIES=debug` を設定
3. C# の `TestMeaning()` メソッドを呼び出し、初期値（42）を表示
4. ユーザーが「Update」ボタンをクリック（最大 2 回）
5. C# の `Update()` メソッドで `DeltaHelper.Update()` を呼び出し
6. アセンブリにデルタ（メタデータ更新）を適用
7. `TestMeaning()` を再度呼び出し、更新された値を表示

**画面遷移**：本画面は単一画面のサンプルアプリケーションであり、他画面への遷移はありません。

**権限による表示制御**：本画面は認証・認可機能を持たないデモアプリケーションであり、権限による表示制御はありません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Mono | 主機能 | WebAssembly ランタイム上でホットリロードを実行 |
| 24 | System.Reflection.Emit | 主機能 | 実行時に IL コードを動的に更新 |
| 25 | System.Reflection.Metadata | 主機能 | アセンブリメタデータの読み取りと更新 |
| 59 | WebAssembly Workload | 補助機能 | WebAssembly アプリケーションのビルドと実行をサポート |

## 画面種別

インタラクティブデモ画面（単一画面）

## URL/ルーティング

- ローカル開発: `http://localhost:8000/index.html`
- 静的ファイルパス: `src/mono/sample/mbr/browser/wwwroot/index.html`

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| - | - | - | 本画面にテキスト入力項目はありません |

## 表示項目

| 項目ID | 項目名 | 要素タイプ | 説明 |
|--------|--------|-----------|------|
| header | 画面タイトル | h3 | 「Wasm Hot Reload Sample」と表示 |
| update | Update ボタン | button | クリックでホットリロードを適用（最大 2 回） |
| out | 計算結果 | span | TestMeaning の結果（42 -> 43 -> 128）を表示 |

## イベント仕様

### 1-画面ロード完了イベント

画面がロードされると、以下の処理が自動的に実行されます:

1. `main.js` がモジュールとして読み込まれる
2. `dotnet.create()` で WebAssembly ランタイムを初期化
3. 環境変数 `DOTNET_MODIFIABLE_ASSEMBLIES=debug` を設定
4. `getAssemblyExports` で C# の公開メソッドを取得
5. `testMeaning()` を呼び出し、初期値を DOM に表示
6. コンソールに "ready" を出力

### 2-Update ボタンクリック（1 回目）

1. `update()` を呼び出し
2. C# の `Update()` メソッドが実行される
3. `DeltaHelper.Update(assm)` でデルタを適用
4. コンソールに "applied update" を出力
5. `testMeaning()` を呼び出し、更新された値（43）を DOM に表示

### 3-Update ボタンクリック（2 回目）

1. `update()` を呼び出し
2. C# の `Update()` メソッドが実行される
3. `DeltaHelper.Update(assm)` で 2 番目のデルタを適用
4. コンソールに "applied update" を出力
5. `testMeaning()` を呼び出し、更新された値（128）を DOM に表示

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面はデータベースを使用しません |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG-001 | 情報 | ready | ランタイム初期化完了後 |
| MSG-002 | 情報 | applied update | Update ボタンクリック後 |
| MSG-003 | 情報 | Hello, World! | C# Main メソッド実行時 |
| MSG-004 | エラー | WASM ERROR {err} | エラー発生時 |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| JavaScript エラー | ランタイム初期化失敗時 | `console.log(\`WASM ERROR \${err}\`)` で出力 |
| デルタ適用エラー | ホットリロード失敗時 | エラー内容をコンソールに出力 |

## 備考

- 環境変数 `DOTNET_MODIFIABLE_ASSEMBLIES=debug` がホットリロード有効化に必須
- デルタファイルは事前にビルド時に生成される
- Update ボタンは最大 2 回まで有効（"upto 2 times" と表示）
- TestMeaning の返り値変化: 42 (初期) -> 43 (1回目更新) -> 128 (2回目更新)
- DeltaHelper クラスは MonoDelta 名前空間で提供
- `System.Reflection.Metadata.ApplyUpdate` を内部的に使用

---

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

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

### 推奨読解順序

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

まず、ホットリロードの仕組みとバージョン管理を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Program.cs | `src/mono/sample/mbr/browser/Program.cs` | 基本バージョン（返り値: 42）を確認 |
| 1-2 | Program_v1.cs | `src/mono/sample/mbr/browser/Program_v1.cs` | 1回目更新後（返り値: 43）を確認 |
| 1-3 | Program_v2.cs | `src/mono/sample/mbr/browser/Program_v2.cs` | 2回目更新後（返り値: 128）を確認 |

**読解のコツ**: 各バージョンのファイルで `TestMeaning()` の返り値が異なることを確認してください。デルタはこの差分から生成されます。

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

処理の起点となるファイル・関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `src/mono/sample/mbr/browser/wwwroot/index.html` | HTML 構造と Update ボタンを確認 |
| 2-2 | main.js | `src/mono/sample/mbr/browser/wwwroot/main.js` | ランタイム初期化とイベント登録を確認 |

**主要処理フロー (main.js)**:
1. **1行目**: dotnet をインポート
2. **4-6行目**: `dotnet.create()` で環境変数設定付きでランタイム初期化
3. **8-9行目**: C# メソッドの取得（update, testMeaning）
4. **11-17行目**: Update ボタンにクリックイベント登録
5. **18行目**: 初期値を DOM に表示

#### Step 3: C# 側のホットリロード実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Program.cs | `src/mono/sample/mbr/browser/Program.cs` | DeltaHelper の使用方法と Update メソッドを確認 |

**主要処理フロー (Program.cs)**:
- **14行目**: `DeltaHelper.Make()` で DeltaHelper インスタンス作成
- **16-19行目**: `Main` - Hello, World! 出力
- **21-25行目**: `TestMeaning` - 42 を返す（初期バージョン）
- **27-32行目**: `Update` - `DeltaHelper.Update()` でデルタを適用

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

```
[Browser] index.html 読み込み
    |
    +-- [JavaScript] main.js 実行
            |
            +-- dotnet.withEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES", "debug")
            |
            +-- dotnet.create() - WebAssembly ランタイム初期化
            |
            +-- getAssemblyExports("WasmDelta.dll") - C# メソッドを取得
            |
            +-- #update.click イベント登録
            |
            +-- testMeaning() 呼び出し（初期値: 42）
            |       |
            |       +-- [C#] TestMeaning() --> return 42
            |
            +-- outElement.innerHTML = "42"
            |
            +-- console.log("ready")

[User] #update クリック (1回目)
    |
    +-- update()
            |
            +-- [C#] Update()
            |       |
            |       +-- typeof(Test).Assembly
            |       +-- replacer.Update(assm)
            |               |
            |               +-- DeltaHelper.Update()
            |                       |
            |                       +-- デルタ1適用
            |                       +-- TestMeaning() --> return 43
            |
            +-- console.log("applied update")
            +-- testMeaning() --> 43
            +-- outElement.innerHTML = "43"

[User] #update クリック (2回目)
    |
    +-- update()
            |
            +-- [C#] Update()
            |       |
            |       +-- replacer.Update(assm)
            |               |
            |               +-- デルタ2適用
            |               +-- TestMeaning() --> return 128
            |
            +-- console.log("applied update")
            +-- testMeaning() --> 128
            +-- outElement.innerHTML = "128"
```

### データフロー図

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

(初期状態)
                     +-- dotnet.create() ----+
                     |   環境変数設定         |
                     +----------+-----------+
                                |
                                v
                     +-- TestMeaning() ----+
                     |   return 42          |  (Program.cs)
                     +----------+-----------+
                                |
                                v
                     outElement.innerHTML = "42"

Update クリック (1回目)
    |
    v
Update() --------> DeltaHelper.Update()
                        |
                        v
               +-- デルタ1適用 ----+
               |   Program_v1.cs    |
               +----------+---------+
                          |
                          v
               TestMeaning() --> return 43
                          |
                          v
               outElement.innerHTML = "43"

Update クリック (2回目)
    |
    v
Update() --------> DeltaHelper.Update()
                        |
                        v
               +-- デルタ2適用 ----+
               |   Program_v2.cs    |
               +----------+---------+
                          |
                          v
               TestMeaning() --> return 128
                          |
                          v
               outElement.innerHTML = "128"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `src/mono/sample/mbr/browser/wwwroot/index.html` | テンプレート | HTML エントリーポイント、Update ボタン |
| main.js | `src/mono/sample/mbr/browser/wwwroot/main.js` | ソース | JavaScript エントリーポイント、イベント登録 |
| Program.cs | `src/mono/sample/mbr/browser/Program.cs` | ソース | C# メインロジック、初期バージョン（42） |
| Program_v1.cs | `src/mono/sample/mbr/browser/Program_v1.cs` | ソース | 1回目更新バージョン（43） |
| Program_v2.cs | `src/mono/sample/mbr/browser/Program_v2.cs` | ソース | 2回目更新バージョン（128） |
| dotnet.js | `_framework/dotnet.js` | ランタイム | .NET WebAssembly ランタイムローダー（ビルド時生成） |
| DeltaHelper | MonoDelta 名前空間 | ライブラリ | メタデータ更新ヘルパー |
