# 機能設計書 1-ref()

## 概要

本ドキュメントは、Vue 3のリアクティビティシステムにおける`ref()` APIの機能設計を記述する。`ref()`は単純な値（プリミティブ値やオブジェクト）をリアクティブにラップし、`.value`プロパティを介してアクセス・更新を行うためのAPIである。

### 本機能の処理概要

`ref()`は、任意の値をリアクティブな参照オブジェクト（Ref）に変換するAPIである。返されるRefオブジェクトは`.value`プロパティを持ち、このプロパティへのアクセスで依存性追跡（track）が行われ、値の変更時に関連するエフェクトが自動的に再実行（trigger）される。

**業務上の目的・背景**：Vueのリアクティビティシステムの基盤となるAPIであり、UIとデータの同期を自動化するために不可欠である。JavaScriptのプリミティブ値（string, number, booleanなど）はProxyで直接ラップできないため、`.value`プロパティを持つオブジェクトでラップすることで、プリミティブ値にもリアクティビティを付与する課題を解決している。

**機能の利用シーン**：Composition API内でコンポーネントのリアクティブな状態を定義する際に使用される。カウンター値、フォーム入力値、トグル状態、非同期データの格納など、あらゆるリアクティブな状態管理に利用される。`<script setup>`構文内や`setup()`関数内で主に使用される。

**主要な処理内容**：
1. 引数として渡された値が既にRefである場合はそのまま返却する
2. `RefImpl`クラスのインスタンスを生成し、値をリアクティブにラップする
3. オブジェクト値の場合は`toReactive()`で内部的にリアクティブプロキシに変換する
4. `.value`のgetterで依存性追跡（`dep.track()`）を実行する
5. `.value`のsetterで値変更を検知し、変更があればエフェクトをトリガー（`dep.trigger()`）する
6. `shallowRef()`による浅いリアクティビティの提供

**関連システム・外部連携**：`@vue/reactivity`パッケージとして提供され、`@vue/runtime-core`および`@vue/runtime-dom`から再エクスポートされる。Depクラス（依存性管理）、ReactiveEffect（エフェクト）、reactive()（オブジェクトのリアクティブ変換）と密接に連携する。

**権限による制御**：特に権限による制御はない。ただし、`shallowRef()`で作成した場合はネストされたプロパティの変更は追跡されない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | App（メイン画面） | 主画面 | replRef, useSSRMode, autoSave, themeの状態管理に使用 |
| 3 | VersionSelect（バージョン選択） | 主画面 | expanded（ドロップダウン展開状態）、versions（バージョン配列）のリアクティブ管理 |
| 5 | Options Panel（コンパイルオプション） | 主画面 | ssrMode（SSRモード切り替え）のリアクティブ管理 |
| 6 | App（メイン画面） | 主画面 | count（カウンター値、初期値0）のリアクティブ状態管理 |

## 機能種別

リアクティビティ管理 / 状態管理API

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| value | T（任意の型） | No | リアクティブにする初期値。省略時はundefined | なし（任意の値を受け付ける） |

### 入力データソース

APIの引数として直接渡される値。画面コンポーネントの`setup()`関数や`<script setup>`内から呼び出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Ref\<T\> | Ref\<UnwrapRef\<T\>\> | `.value`プロパティを持つリアクティブ参照オブジェクト |
| .value | T | リアクティブな値へのアクセスプロパティ |

### 出力先

呼び出し元のComposition APIコンテキストに返却。テンプレート内では自動的にアンラップされる。

## 処理フロー

### 処理シーケンス

```
1. ref(value)が呼び出される
   └─ 引数valueを受け取る（省略時はundefined）
2. createRef(value, false)を呼び出す
   └─ shallowフラグはfalse（深いリアクティビティ）
3. isRef(rawValue)で既にRefかどうかを判定
   └─ 既にRefの場合: そのまま返却（早期リターン）
4. new RefImpl(rawValue, shallow)でRefインスタンスを生成
   └─ _rawValue: shallow ? value : toRaw(value)
   └─ _value: shallow ? value : toReactive(value)
   └─ dep: new Dep()（依存性管理オブジェクト）
5. Refオブジェクトを返却
```

### フローチャート

```mermaid
flowchart TD
    A[ref value が呼び出される] --> B[createRef value, false]
    B --> C{isRef rawValue ?}
    C -->|Yes| D[rawValueをそのまま返却]
    C -->|No| E[new RefImpl rawValue, shallow]
    E --> F{shallow?}
    F -->|Yes| G[_rawValue = value, _value = value]
    F -->|No| H[_rawValue = toRaw value]
    H --> I{isObject value ?}
    I -->|Yes| J[_value = reactive value]
    I -->|No| K[_value = value]
    G --> L[Refオブジェクトを返却]
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 既存Ref検出 | 引数が既にRefオブジェクトの場合はそのまま返却する | isRef(rawValue)がtrueの場合 |
| BR-02 | 深いリアクティブ変換 | オブジェクト値はreactive()で再帰的にリアクティブプロキシに変換される | ref()使用時（shallow=false）かつ値がオブジェクトの場合 |
| BR-03 | 浅いリアクティブ | shallowRef()使用時はネストされたプロパティの変更は追跡されない | shallowRef()使用時（shallow=true） |
| BR-04 | 変更検知 | Object.is()による同値判定で値変更を検知する | .valueへの代入時 |
| BR-05 | 自動アンラップ | テンプレート内ではRefは自動的にアンラップされ、.valueなしでアクセス可能 | テンプレートレンダリング時 |

### 計算ロジック

値変更の検知は`hasChanged(newValue, oldValue)`（Object.isの否定）で判定される。同じ値への再代入ではエフェクトはトリガーされない。

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

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

該当なし（フロントエンドの状態管理APIであり、データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 開発者警告 | toRefs()にリアクティブでないオブジェクトが渡された場合 | 開発モードでコンソール警告を出力 |

### リトライ仕様

該当なし

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

該当なし（メモリ内状態管理のためトランザクション不要）

## パフォーマンス要件

- `ref()`の生成はO(1)の計算量
- `.value`のgetterは依存性追跡のオーバーヘッドを含むが、Linkベースの双方向リンクリストにより効率的に管理される
- `.value`のsetterはhasChanged()による比較の後、変更がある場合のみバッチ処理でエフェクトを通知する

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

特になし（フロントエンドの状態管理APIであり、セキュリティ上の懸念はない）

## 備考

- `shallowRef()`は浅いリアクティビティを提供し、大きなオブジェクトのパフォーマンス最適化に有用
- `triggerRef()`でshallowRefの依存エフェクトを手動トリガー可能
- `customRef()`で依存性追跡とトリガーを明示的に制御するカスタムRefを作成可能
- `toRef()`, `toRefs()`, `unref()`, `toValue()`, `proxyRefs()`など関連ユーティリティが充実している
- `@vue/reactivity`パッケージのindex.tsから公開エクスポートされる

---

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

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

### 推奨読解順序

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

まず、Refの型定義と依存性管理のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ref.ts | `packages/reactivity/src/ref.ts` | Ref<T>インターフェース定義（28-37行目）。`.value`のgetter/setterを持つ構造 |
| 1-2 | constants.ts | `packages/reactivity/src/constants.ts` | ReactiveFlags列挙型（17-24行目）。IS_REF='__v_isRef'等のフラグ定義 |
| 1-3 | dep.ts | `packages/reactivity/src/dep.ts` | Depクラス（67-205行目）。依存性追跡の中核。Link双方向リンクリスト構造 |

**読解のコツ**: VueのリアクティビティシステムはProxy + Dep + Linkの3層構造で成り立っている。RefはProxyを使わず、getter/setterでDep.track()/Dep.trigger()を直接呼び出すシンプルな構造であることに注意。

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

`ref()`関数の定義と内部のファクトリ関数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ref.ts | `packages/reactivity/src/ref.ts` | ref()関数定義（58-65行目）。createRef(value, false)を呼び出す |

**主要処理フロー**:
1. **58-65行目**: `ref()`関数のオーバーロード定義と実装。型推論対応の複数シグネチャ
2. **63-65行目**: 実装部分。`createRef(value, false)`を呼び出し、shallowフラグはfalse
3. **103-108行目**: `createRef()`関数。既存Refチェック後、RefImplインスタンスを生成

#### Step 3: RefImplクラスの内部実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ref.ts | `packages/reactivity/src/ref.ts` | RefImplクラス（113-164行目）。コンストラクタ、getter、setter |

**主要処理フロー**:
- **113-126行目**: RefImplクラス定義。`_value`, `_rawValue`, `dep`フィールド。コンストラクタでtoRaw/toReactiveを適用
- **128-139行目**: `get value()`。`dep.track()`を呼び出して依存性を記録し、`_value`を返却
- **141-163行目**: `set value()`。hasChanged()で変更を検知し、dep.trigger()でエフェクトを通知

#### Step 4: 関連ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ref.ts | `packages/reactivity/src/ref.ts` | shallowRef()（90-101行目）、triggerRef()（191-205行目）、customRef()（328-330行目） |
| 4-2 | ref.ts | `packages/reactivity/src/ref.ts` | unref()（231-233行目）、toValue()（251-253行目）、toRef()（465-496行目）、toRefs()（345-354行目） |
| 4-3 | ref.ts | `packages/reactivity/src/ref.ts` | proxyRefs()（279-285行目）。リアクティブオブジェクト内のRef自動アンラップ |

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

```
ref(value)
    |
    +-- createRef(value, shallow=false)
    |       |
    |       +-- isRef(rawValue)     // 既存Refチェック
    |       |
    |       +-- new RefImpl(rawValue, shallow)
    |               |
    |               +-- toRaw(value)         // 生の値を取得
    |               +-- toReactive(value)    // オブジェクトならreactive()変換
    |               +-- new Dep()            // 依存性管理オブジェクト生成
    |
    +-- [.value getter]
    |       +-- dep.track()          // 依存性追跡
    |               +-- new Link(activeSub, dep)  // Subscriber-Dep間リンク生成
    |
    +-- [.value setter]
            +-- hasChanged(newValue, oldValue)  // 変更検知
            +-- dep.trigger()        // エフェクトトリガー
                    +-- dep.notify()
                            +-- startBatch() / endBatch()
```

### データフロー図

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

value (any)   ───>  ref(value)                    ───>  Ref<UnwrapRef<T>>
                        |
                    createRef()
                        |
                    RefImpl constructor
                        |
                    +---------+-----------+
                    |                     |
              toRaw(value)         toReactive(value)
                    |                     |
              _rawValue             _value (reactive proxy or raw)
                    |                     |
                    +----------+----------+
                               |
                          Ref object
                               |
                    +----------+----------+
                    |                     |
              .value GET            .value SET
                    |                     |
              dep.track()           dep.trigger()
                    |                     |
              依存関係記録          エフェクト再実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ref.ts | `packages/reactivity/src/ref.ts` | ソース | ref()のメイン実装。RefImpl, ShallowRef, CustomRefImpl等 |
| dep.ts | `packages/reactivity/src/dep.ts` | ソース | Dep/Linkクラスの実装。依存性追跡とトリガーの中核 |
| reactive.ts | `packages/reactivity/src/reactive.ts` | ソース | toReactive(), toRaw()の実装。オブジェクト値のリアクティブ変換 |
| effect.ts | `packages/reactivity/src/effect.ts` | ソース | ReactiveEffect, activeSub, shouldTrack。エフェクト実行基盤 |
| constants.ts | `packages/reactivity/src/constants.ts` | ソース | ReactiveFlags, TrackOpTypes, TriggerOpTypes列挙型 |
| index.ts | `packages/reactivity/src/index.ts` | ソース | パッケージエクスポート定義 |
