# 通知設計書 1-WebSocket接続通知

## 概要

本ドキュメントは、Bun の Hot Module Reloading (HMR) 機能において、WebSocket 接続が確立された際にブラウザのコンソールに表示される接続成功メッセージ通知の設計を記載する。

### 本通知の処理概要

この通知は、開発サーバーとブラウザクライアント間の WebSocket 接続が正常に確立されたことを開発者に知らせるためのコンソール出力である。HMR 機能の動作状況を開発者が把握できるようにすることで、開発体験を向上させる役割を果たす。

**業務上の目的・背景**：開発時に HMR が正しく動作しているかを開発者が即座に確認できるようにするため、WebSocket 接続の確立をコンソールに通知する。これにより、ファイル変更時のホットリロードが利用可能な状態であることを明示し、接続問題のトラブルシューティングを容易にする。

**通知の送信タイミング**：ブラウザクライアントが開発サーバーの HMR エンドポイント (`/_bun/hmr`) に対して WebSocket 接続を確立し、`onopen` イベントが発火した初回接続時に送信される。再接続時は別の通知（WebSocket再接続通知）が使用される。

**通知の受信者**：ブラウザのコンソールを通じて開発者に通知される。この通知はクライアントサイドの JavaScript によって `console.info()` メソッドで出力されるため、ブラウザの開発者ツールを開いている開発者のみが確認できる。

**通知内容の概要**：`[Bun] Hot-module-reloading socket connected, waiting for changes...` という固定メッセージがコンソールに出力される。このメッセージは、接続が成功し、ファイル変更の監視が開始されたことを示す。

**期待されるアクション**：開発者はこのメッセージを確認することで、HMR 機能が正常に動作していることを把握できる。特別なアクションは不要だが、このメッセージが表示されない場合は接続問題を調査する必要がある。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（WebSocket onopen イベントハンドラ内で即座に実行） |
| 優先度 | 低（情報通知のため） |
| リトライ | 無（コンソール出力は失敗しない） |

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

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

## 通知テンプレート

### コンソール出力

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

### 本文テンプレート

```
[Bun] Hot-module-reloading socket connected, waiting for changes...
```

### 添付ファイル

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

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| WebSocket イベント | `onopen` (初回接続時) | `firstConnection === true` | WebSocket 接続が初めて確立されたとき |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 再接続時 | 初回接続ではなく再接続の場合は、この通知ではなく「WebSocket再接続通知」が使用される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ブラウザページ読み込み] --> B[initWebSocket 関数呼び出し]
    B --> C[WebSocket オブジェクト作成]
    C --> D[ws.onopen に onFirstOpen 設定]
    D --> E{WebSocket 接続確立}
    E -->|成功| F[onFirstOpen 関数実行]
    F --> G[console.info でメッセージ出力]
    G --> H[onStatusChange コールバック呼び出し]
    H --> I[送信キューのドレイン]
    I --> J[終了]
    E -->|失敗| K[onError 処理]
    K --> L[onClose で再接続処理開始]
```

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

### 参照テーブル一覧

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

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 接続失敗 | WebSocket 接続がタイムアウトまたは拒否された場合 | この通知は発行されず、onClose ハンドラで再接続処理が開始される |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 該当なし（コンソール出力は失敗しない） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（初回接続時のみ発生） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

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

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

- この通知は開発環境でのみ使用されることを想定している
- 機密情報は含まれない（固定メッセージのみ）
- 本番環境では HMR 機能自体が無効化されるべきである

## 備考

- この通知は Bun の開発サーバー（DevServer）の HMR 機能の一部として実装されている
- `src/bake/client/websocket.ts` の `onFirstOpen` 関数で実装されている
- 接続成功後、`onStatusChange` コールバックが `true` を引数として呼び出され、`bun:ws:connect` イベントが発行される

---

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

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

### 推奨読解順序

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

WebSocket 接続管理に使用されるインターフェースと型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | websocket.ts | `src/bake/client/websocket.ts` | `WebSocketWrapper` インターフェース（41-54行目）で WebSocket のラッパー構造を理解する |

**読解のコツ**: TypeScript のインターフェース定義で、`wrapped` プロパティが実際の WebSocket インスタンスを保持し、再接続時に再割り当てされることに注目する。

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

HMR クライアントの初期化処理と WebSocket 接続の開始を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | HMR ランタイムのエントリーポイント。203-207行目で `initWebSocket` を呼び出している |
| 2-2 | websocket.ts | `src/bake/client/websocket.ts` | `initWebSocket` 関数（74-198行目）が WebSocket 接続を初期化する |

**主要処理フロー**:
1. **203行目**: `initWebSocket(handlers, { onStatusChange })` で WebSocket 初期化
2. **78行目**: URL の正規化（http -> ws, https -> wss）
3. **190-195行目**: WebSocket オブジェクト作成とイベントハンドラ設定

#### Step 3: 接続成功時の通知処理を理解する

WebSocket 接続確立時に実行される処理を詳細に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | websocket.ts | `src/bake/client/websocket.ts` | `onFirstOpen` 関数（122-133行目）で接続成功メッセージが出力される |

**主要処理フロー**:
- **123行目**: `console.info("[Bun] Hot-module-reloading socket connected, waiting for changes...");` でメッセージ出力
- **124行目**: `onStatusChange?.(true)` でコールバック呼び出し
- **127-132行目**: 送信キューのドレイン処理

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

```
hmr-runtime-client.ts
    │
    └─ initWebSocket(handlers, options)
           │
           ├─ normalizeWebSocketURL(url)
           │      └─ URL プロトコル変換
           │
           ├─ new WebSocket(url)
           │      └─ ブラウザ WebSocket API
           │
           └─ ws.onopen = onFirstOpen
                  │
                  ├─ console.info() ← 通知出力
                  │
                  └─ onStatusChange(true)
                         └─ emitEvent('bun:ws:connect')
```

### データフロー図

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

ページ読み込み ───────▶ initWebSocket() ──────────────▶ WebSocket 接続開始
                              │
                              ▼
                       WebSocket.onopen
                              │
                              ▼
                       onFirstOpen()
                              │
                              ▼
                       console.info() ────────────────▶ [Bun] Hot-module-reloading...
                              │
                              ▼
                       onStatusChange(true) ──────────▶ bun:ws:connect イベント発行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| websocket.ts | `src/bake/client/websocket.ts` | ソース | WebSocket 接続管理とイベントハンドリング |
| hmr-runtime-client.ts | `src/bake/hmr-runtime-client.ts` | ソース | HMR クライアントのエントリーポイント |
| hmr-module.ts | `src/bake/hmr-module.ts` | ソース | HMR イベント発行（`emitEvent` 関数） |
| HmrSocket.zig | `src/bake/DevServer/HmrSocket.zig` | ソース | サーバーサイドの WebSocket ハンドリング |
