# 画面設計書 1-Wasm Browser Sample

## 概要

本ドキュメントは、.NET WebAssembly の基本的なブラウザサンプル画面「Wasm Browser Sample」の設計内容を記載した画面設計書です。本画面は .NET Runtime リポジトリにおける WebAssembly 機能のデモンストレーション用サンプルアプリケーションとして提供されています。

### 本画面の処理概要

本画面は、ブラウザ上で .NET WebAssembly ランタイムを使用して C# コードを実行し、その結果を画面に表示する最もシンプルなサンプルアプリケーションです。

**業務上の目的・背景**：本画面は、.NET WebAssembly ランタイム（Mono）がブラウザ環境で正しく動作することを検証・デモンストレーションするために作成されました。「究極の問いへの答え」（42）を表示するという分かりやすい例を通じて、JavaScript と C# 間の相互運用（JSImport/JSExport）の基本的な使い方を開発者に示すことを目的としています。新規に .NET WebAssembly 開発を始める開発者が、プロジェクト構成やビルド方法、JavaScript-C# 連携の仕組みを学ぶための入門用サンプルとして位置付けられています。

**画面へのアクセス方法**：ローカル開発サーバー（通常は `http://localhost:8000/`）にブラウザでアクセスすることで画面を表示できます。ビルドは `dotnet build` コマンドで行い、`dotnet run` でローカルサーバーを起動します。

**主要な操作・処理内容**：
1. 画面ロード時に JavaScript（main.js）が .NET WebAssembly ランタイムを初期化
2. C# 側の `Sample.Test.Main` メソッドが実行され、`DisplayMeaning(42)` を呼び出し
3. JSImport 経由で JavaScript の `displayMeaning` 関数が呼び出され、DOM の `#out` 要素に「42」を表示
4. JavaScript 側から `PrintMeaning` メソッドを呼び出し、Promise で渡された値（42）をコンソールに出力
5. `dotnet.runMainAndExit()` でアプリケーションを正常終了

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Mono | 主機能 | WebAssembly ランタイム上で .NET コードを実行するメイン処理 |
| 59 | WebAssembly Workload | 主機能 | WebAssembly アプリケーションのビルドと実行をサポート |
| 40 | WasmAppBuilder | 補助機能 | WebAssembly アプリケーションのビルドサポート |

## 画面種別

デモ表示画面（単一画面）

## URL/ルーティング

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

## 入出力項目

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

## 表示項目

| 項目ID | 項目名 | 要素タイプ | 説明 |
|--------|--------|-----------|------|
| header | 画面タイトル | h3 | 「Wasm Browser Sample」と表示 |
| out | 計算結果 | span | 「究極の問いへの答え」の値（42）を表示 |

## イベント仕様

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

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

1. `main.js` がモジュールとして読み込まれる
2. dotnet.js から `dotnet` と `exit` をインポート
3. `dotnet.create()` で WebAssembly ランタイムを初期化
4. `setModuleImports` で JavaScript 関数を C# から呼び出せるように登録
5. `getAssemblyExports` で C# の公開メソッドを取得
6. `PrintMeaning` を呼び出し（2秒後に42を返す Promise を渡す）
7. `dotnet.runMainAndExit()` で C# の Main メソッドを実行

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

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG-001 | 情報 | Meaning of life is 42 | PrintMeaning 実行時にコンソールに出力 |
| MSG-002 | 情報 | Program has exited normally. | 正常終了時にコンソールに出力 |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| JavaScript エラー | WebAssembly ランタイム初期化失敗時 | `exit(2, err)` を呼び出してエラーコード2で終了 |
| ネットワークエラー | アセンブリ読み込み失敗時 | ブラウザコンソールにエラー出力後、終了 |

## 備考

- 本サンプルは .NET WebAssembly の入門用として最もシンプルな構成となっている
- `appendElementOnExit: true` 設定により、終了時に状態が DOM に表示される
- `exitOnUnhandledError: true` 設定により、未処理例外発生時にアプリケーションが終了する
- `forwardConsole: true` 設定により、C# の Console.WriteLine がブラウザコンソールに転送される

---

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

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

### 推奨読解順序

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

まず、JavaScript と C# 間で受け渡されるデータの構造とインターフェースを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Program.cs | `src/mono/sample/wasm/browser/Program.cs` | JSImport/JSExport 属性によるインターフェース定義を確認 |

**読解のコツ**: C# の `[JSImport]` 属性は JavaScript 関数を C# から呼び出すためのマーカー、`[JSExport]` 属性は C# メソッドを JavaScript から呼び出し可能にするマーカーです。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `src/mono/sample/wasm/browser/wwwroot/index.html` | HTML 構造と main.js の読み込み方法を確認 |
| 2-2 | main.js | `src/mono/sample/wasm/browser/wwwroot/main.js` | JavaScript エントリーポイントとして dotnet ランタイム初期化処理を確認 |

**主要処理フロー (main.js)**:
1. **4行目**: `dotnet` と `exit` を `_framework/dotnet.js` からインポート
2. **6-9行目**: `displayMeaning` 関数定義 - DOM 更新とコンソール出力
3. **16-18行目**: `dotnet.create()` で WebAssembly ランタイムを初期化
4. **20-26行目**: `setModuleImports` で JavaScript 関数を C# に公開
5. **28行目**: `getAssemblyExports` で C# の公開メソッドを取得
6. **29行目**: `PrintMeaning` を呼び出し（Promise を引数に渡す）
7. **31行目**: `dotnet.runMainAndExit()` で Main メソッドを実行して終了

#### Step 3: C# 側の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Program.cs | `src/mono/sample/wasm/browser/Program.cs` | C# 側の Main メソッドと JSImport/JSExport の実装を確認 |

**主要処理フロー (Program.cs)**:
- **13-17行目**: `Main` メソッド - `DisplayMeaning(42)` を呼び出して終了
- **19-20行目**: `DisplayMeaning` - JSImport で main.js の displayMeaning 関数を呼び出し
- **22-26行目**: `PrintMeaning` - JSExport で JavaScript から呼び出し可能な非同期メソッド

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

```
[Browser] index.html 読み込み
    |
    +-- [JavaScript] main.js 実行
            |
            +-- dotnet.create() - WebAssembly ランタイム初期化
            |       |
            |       +-- [C#] アセンブリ読み込み
            |
            +-- setModuleImports() - JS関数をC#に公開
            |
            +-- getAssemblyExports() - C#メソッドを取得
            |
            +-- exports.Sample.Test.PrintMeaning(promise)
            |       |
            |       +-- [C#] PrintMeaning() 実行
            |               |
            |               +-- Console.WriteLine() - コンソール出力
            |
            +-- dotnet.runMainAndExit()
                    |
                    +-- [C#] Sample.Test.Main() 実行
                            |
                            +-- DisplayMeaning(42)
                                    |
                                    +-- [JavaScript] displayMeaning(42)
                                            |
                                            +-- DOM更新 (#out に 42 を表示)
```

### データフロー図

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

                     +-- dotnet.create() ----+
                     |   (ランタイム初期化)   |
                     +----------------------+
                              |
Promise(42) ---------> PrintMeaning() ---------> Console.WriteLine()
                              |                    (コンソール出力)
                              v
                     +-- Main() ----+
                     |              |
                     +------+------+
                            |
                            v
                     DisplayMeaning(42)
                            |
                            v
                     +-- displayMeaning() --+
                     |   (JavaScript)       |
                     +----------+-----------+
                                |
                                v
                     document.getElementById("out")
                            .innerHTML = "42"
                         (DOM 表示更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `src/mono/sample/wasm/browser/wwwroot/index.html` | テンプレート | HTML エントリーポイント、画面レイアウト定義 |
| main.js | `src/mono/sample/wasm/browser/wwwroot/main.js` | ソース | JavaScript エントリーポイント、ランタイム初期化 |
| Program.cs | `src/mono/sample/wasm/browser/Program.cs` | ソース | C# メインロジック、JSImport/JSExport 定義 |
| dotnet.js | `_framework/dotnet.js` | ランタイム | .NET WebAssembly ランタイムローダー（ビルド時生成） |
