# 機能設計書 106-node:inspector

## 概要

本ドキュメントは、BunにおけるNode.js互換の`node:inspector`モジュールの機能設計を記述したものである。このモジュールは、V8/JavaScriptCoreインスペクターとの連携機能を提供する。

### 本機能の処理概要

`node:inspector`モジュールは、JavaScriptデバッガーやプロファイラーとの通信機能を提供する。Bunでは**CPUプロファイラーAPI（Profiler.*)が実装済み**であり、その他のインスペクター機能は未実装（スタブ）である。

**業務上の目的・背景**：アプリケーションのパフォーマンス分析やデバッグは開発・運用において重要である。CPUプロファイラーにより、コード内のボトルネックを特定し、最適化の指針を得ることができる。Node.js互換のAPIを提供することで、既存のプロファイリングツールやワークフローをBunでも活用可能にする。

**機能の利用シーン**：
- CPUプロファイルの収集（パフォーマンス分析）
- プロファイルデータのJSON出力（可視化ツールへの連携）
- サンプリング間隔の調整

**主要な処理内容**：
1. `Session`クラス: インスペクターセッションの管理
2. `Profiler.enable`/`disable`: プロファイラーの有効化/無効化
3. `Profiler.start`/`stop`: CPUプロファイリングの開始/停止
4. `Profiler.setSamplingInterval`: サンプリング間隔の設定

**関連システム・外部連携**：
- JavaScriptCore: ネイティブプロファイラー機能
- Chrome DevTools Protocol: 互換性のあるメッセージ形式

**権限による制御**：特になし

## 関連画面

本機能はバックエンドモジュールであり、直接的な関連画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

プロファイリング / デバッガー連携

## 入力仕様

### 入力パラメータ

#### `Session.post(method, params, callback)`

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| method | string | Yes | インスペクターメソッド名 | 文字列 |
| params | object | No | メソッドパラメータ | - |
| callback | function | No | コールバック関数 | 関数であること |

#### サポートされるメソッド

| メソッド | 説明 | パラメータ |
|---------|------|-----------|
| Profiler.enable | プロファイラーを有効化 | なし |
| Profiler.disable | プロファイラーを無効化 | なし |
| Profiler.start | プロファイリング開始 | なし |
| Profiler.stop | プロファイリング停止、プロファイル返却 | なし |
| Profiler.setSamplingInterval | サンプリング間隔設定 | { interval: number } |

### 入力データソース

- `Session.post()`メソッドの引数

## 出力仕様

### 出力データ

#### `Profiler.stop`の戻り値

| 項目名 | 型 | 説明 |
|--------|-----|------|
| profile | object | CPUプロファイルデータ |
| profile.nodes | array | コールスタックノード |
| profile.startTime | number | 開始時刻（マイクロ秒） |
| profile.endTime | number | 終了時刻（マイクロ秒） |
| profile.samples | array | サンプルIDの配列 |
| profile.timeDeltas | array | サンプル間の時間差 |

#### その他メソッドの戻り値

| メソッド | 戻り値 |
|---------|-------|
| Profiler.enable | {} |
| Profiler.disable | {} |
| Profiler.start | {} |
| Profiler.setSamplingInterval | {} |

### 出力先

- コールバック関数の第2引数
- 同期呼び出し時は戻り値

## 処理フロー

### 処理シーケンス（CPUプロファイリング）

```
1. Session作成
   └─ new inspector.Session()
2. 接続
   └─ session.connect()
3. プロファイラー有効化
   └─ session.post('Profiler.enable')
4. サンプリング間隔設定（オプション）
   └─ session.post('Profiler.setSamplingInterval', { interval: 100 })
5. プロファイリング開始
   └─ session.post('Profiler.start')
6. アプリケーション実行
   └─ [プロファイル対象のコードを実行]
7. プロファイリング停止
   └─ session.post('Profiler.stop', callback)
8. プロファイルデータ取得
   └─ callback(null, { profile: {...} })
9. 切断
   └─ session.disconnect()
```

### フローチャート

```mermaid
flowchart TD
    A[Session作成] --> B[connect]
    B --> C[Profiler.enable]
    C --> D{interval設定?}
    D -->|Yes| E[setSamplingInterval]
    D -->|No| F[Profiler.start]
    E --> F
    F --> G[アプリ実行]
    G --> H[Profiler.stop]
    H --> I[プロファイルデータ返却]
    I --> J[disconnect]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-601 | 二重接続禁止 | 既に接続中のSessionは再接続不可 | connect()呼び出し時 |
| BR-602 | enable必須 | Profiler.startの前にenableが必要 | Profiler.start時 |
| BR-603 | interval変更制限 | プロファイラー実行中はinterval変更不可 | setSamplingInterval時 |
| BR-604 | 未実装メソッド | サポート外メソッドはエラーを返す | 不明なメソッド |

### 計算ロジック

**サンプリング間隔**：
- デフォルト: 1000マイクロ秒（1ms）
- `setSamplingInterval`で変更可能
- 単位はマイクロ秒

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーケース | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Session is already connected | Error | 既に接続中にconnect | disconnect後にconnect |
| Session is not connected | Error | 未接続でpost | connect後にpost |
| Profiler is not enabled | Error | enable前にstart | enable後にstart |
| Profiler is not started | Error | start前にstop | start後にstop |
| Cannot change sampling interval | Error | 実行中にinterval変更 | stop後に変更 |
| interval must be a positive number | Error | intervalが不正 | 正の数値を指定 |
| Inspector method not supported | Error | 未サポートメソッド | サポートメソッドを使用 |

### リトライ仕様

本機能はリトライを行わない。

## トランザクション仕様

本機能はトランザクションを使用しない。

## パフォーマンス要件

- プロファイリングは本番環境でも使用可能な低オーバーヘッド
- サンプリング間隔を大きくするとオーバーヘッドが減少

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

- プロファイルデータにはコードの構造情報が含まれる
- `open()`/`close()`/`waitForDebugger()`は未実装（セキュリティ上の理由も考慮）

## 備考

- `open()`、`close()`、`waitForDebugger()`は未実装（throwNotImplemented）
- `url()`は常にundefinedを返す（Node.js API仕様に準拠）
- `inspector.console`はglobalThis.consoleのラッパー
- Coverage API（getBestEffortCoverage等）は未サポート

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | inspector.ts | `src/js/node/inspector.ts` | モジュールのエクスポートとスタブ関数 |

**読解のコツ**:
- **7-10行目**: ネイティブプロファイラー関数の読み込み
- **12-28行目**: スタブ関数（open, close, url, waitForDebugger）
- **145-152行目**: モジュールエクスポート

#### Step 2: Sessionクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inspector.ts | `src/js/node/inspector.ts` | Sessionクラスの実装 |

**主要処理フロー**:
1. **30-31行目**: プライベートフィールド（#connected, #profilerEnabled）
2. **34-43行目**: `connect`/`connectToMainThread`メソッド
3. **45-50行目**: `disconnect`でプロファイラーを停止
4. **52-90行目**: `post`メソッドでメソッドディスパッチ
5. **92-135行目**: `#handleMethod`で各メソッドの処理

#### Step 3: Profilerメソッドの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inspector.ts | `src/js/node/inspector.ts` | #handleMethodの詳細 |

**主要処理フロー**:
- **94-96行目**: `Profiler.enable`でフラグを立てる
- **98-103行目**: `Profiler.disable`でプロファイラー停止
- **105-108行目**: `Profiler.start`でプロファイリング開始
- **110-116行目**: `Profiler.stop`でプロファイルをJSON返却
- **118-124行目**: `Profiler.setSamplingInterval`で間隔設定

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

```
JavaScript
    │
    ├─ new inspector.Session()
    │
    ├─ session.connect()
    │      └─ #connected = true
    │
    ├─ session.post('Profiler.enable')
    │      └─ #handleMethod('Profiler.enable')
    │             └─ #profilerEnabled = true
    │
    ├─ session.post('Profiler.start')
    │      └─ #handleMethod('Profiler.start')
    │             └─ startCPUProfiler() [C++ネイティブ]
    │
    ├─ session.post('Profiler.stop', callback)
    │      └─ #handleMethod('Profiler.stop')
    │             └─ stopCPUProfiler() [C++ネイティブ]
    │                    └─ JSON.parse() → { profile: {...} }
    │
    └─ session.disconnect()
           └─ if (isCPUProfilerRunning()) stopCPUProfiler()
```

### データフロー図

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

session.post(method) ───────▶ #handleMethod(method) ────▶ result/Error
                                    │
                              [Profiler.start]
                                    │
                                    ▼
                              startCPUProfiler() ────────▶ プロファイリング開始
                                    │
                              [Profiler.stop]
                                    │
                                    ▼
                              stopCPUProfiler() ─────────▶ { profile: {...} }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inspector.ts | `src/js/node/inspector.ts` | ソース | inspectorモジュールの実装 |
| JSInspectorProfiler.cpp | `src/bun.js/bindings/JSInspectorProfiler.cpp` | ソース | ネイティブプロファイラー |
| shared.ts | `src/js/internal/shared.ts` | ソース | throwNotImplemented等 |
