# 機能設計書 12-stream

## 概要

本ドキュメントは、Node.jsのStreamモジュール（ストリームAPI）の機能設計を記述したものである。

### 本機能の処理概要

Stream機能は、Node.jsにおいてデータを連続的に処理するための抽象化レイヤーを提供する。大量のデータを一度にメモリに読み込むのではなく、チャンク（断片）単位で処理することで、メモリ効率の良いデータ処理を実現する。

**業務上の目的・背景**：ファイル処理、ネットワーク通信、データ変換など、大量データを扱う場面でメモリ効率とレスポンス性を両立させる必要がある。ストリームはこれらの要件を満たすための基盤機能である。

**機能の利用シーン**：
- 大容量ファイルの読み書き（fs.createReadStream/createWriteStream）
- HTTP リクエスト/レスポンスの処理
- 圧縮/解凍処理（zlib）
- 暗号化/復号化処理（crypto）
- データ変換パイプライン
- リアルタイムデータ処理

**主要な処理内容**：
1. Readable: データソースからの読み取り
2. Writable: データシンクへの書き込み
3. Duplex: 読み取りと書き込みの両方
4. Transform: データ変換（Duplexの特殊形態）
5. PassThrough: データをそのまま通過（Transformの特殊形態）
6. pipeline: 複数ストリームの連結
7. finished: ストリーム終了の検出

**関連システム・外部連携**：
- fs: ファイルストリーム
- http/https: HTTPストリーム
- net: TCPソケットストリーム
- zlib: 圧縮ストリーム
- crypto: 暗号化ストリーム
- child_process: プロセスのstdin/stdout/stderr

**権限による制御**：特になし。ストリームはユーザーランドで自由に使用可能。

## 関連画面

本機能はCLI/APIレベルの機能であり、直接関連する画面はない。

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

## 機能種別

データ処理 / I/O抽象化 / イベント駆動処理

## 入力仕様

### 入力パラメータ

#### Readable Stream オプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| highWaterMark | number | No | 内部バッファの閾値（バイト数）| デフォルト16KB |
| encoding | string | No | 文字列として読み取る場合のエンコーディング | 有効なエンコーディング |
| objectMode | boolean | No | オブジェクトモードの有効化 | - |
| autoDestroy | boolean | No | 終了時の自動破棄 | デフォルトtrue |
| signal | AbortSignal | No | キャンセル用シグナル | - |

#### Writable Stream オプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| highWaterMark | number | No | 内部バッファの閾値（バイト数）| デフォルト16KB |
| decodeStrings | boolean | No | 文字列をBufferにデコードするか | デフォルトtrue |
| objectMode | boolean | No | オブジェクトモードの有効化 | - |
| autoDestroy | boolean | No | 終了時の自動破棄 | デフォルトtrue |
| signal | AbortSignal | No | キャンセル用シグナル | - |

### 入力データソース

- アプリケーションコード（push/write呼び出し）
- ファイルシステム（fs.createReadStream）
- ネットワーク（HTTPリクエスト、ソケット）
- 他のストリーム（pipe経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| chunk | Buffer/string/any | ストリームから読み取られたデータチャンク |
| イベント | Event | data, end, error, close等のイベント |

### 出力先

- アプリケーションコード（dataイベント、read()）
- ファイルシステム（fs.createWriteStream）
- ネットワーク（HTTPレスポンス、ソケット）
- 他のストリーム（pipe先）

## 処理フロー

### 処理シーケンス

```
1. ストリーム生成
   └─ オプションに基づく初期化
2. データフロー開始
   └─ Readable: _read()実装の呼び出し
   └─ Writable: write()の受付開始
3. データ処理
   └─ バックプレッシャー制御
   └─ バッファリング
4. 終了処理
   └─ end/finish イベント発火
   └─ close イベント発火
```

### フローチャート

```mermaid
flowchart TD
    A[ストリーム生成] --> B{ストリーム種別}
    B -->|Readable| C[_read実装]
    B -->|Writable| D[_write実装]
    B -->|Duplex| E[_read + _write実装]
    B -->|Transform| F[_transform実装]

    C --> G[push/dataイベント]
    D --> H[write/drainイベント]
    E --> G
    E --> H
    F --> I[push変換後データ]

    G --> J{バックプレッシャー?}
    J -->|Yes| K[pause/resume]
    J -->|No| L[継続処理]

    H --> M{バッファ満杯?}
    M -->|Yes| N[drainを待機]
    M -->|No| O[継続書き込み]

    K --> L
    N --> O

    L --> P[end/finish]
    O --> P
    P --> Q[close]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | バックプレッシャー | 消費側が追いつかない場合、生産側を一時停止 | highWaterMark超過時 |
| BR-002 | オブジェクトモード | objectMode時はhighWaterMarkはオブジェクト数 | objectMode: true時 |
| BR-003 | 自動破棄 | autoDestroy: trueの場合、end/error時に自動destroy | デフォルト有効 |
| BR-004 | pipe伝播 | pipe先でエラー発生時、元ストリームもエラー | pipeline使用時 |

### 計算ロジック

#### highWaterMark取得
```javascript
function getHighWaterMark(state, options, duplexKey, isDuplex) {
  const hwm = options[duplexKey];
  if (hwm != null) return hwm;
  if (isDuplex) return options.highWaterMark;
  return getDefaultHighWaterMark(state.objectMode);
}
// デフォルト: objectMode ? 16 : 16 * 1024 (16KB)
```

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

本機能はデータベースを直接操作しない。

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_STREAM_PUSH_AFTER_EOF | Error | EOF後にpush | ストリーム終了後のpush禁止 |
| ERR_STREAM_UNSHIFT_AFTER_END_EVENT | Error | end後にunshift | end後のunshift禁止 |
| ERR_STREAM_WRITE_AFTER_END | Error | end後にwrite | end後のwrite禁止 |
| ERR_STREAM_DESTROYED | Error | 破棄後の操作 | destroy後の操作禁止 |
| ERR_METHOD_NOT_IMPLEMENTED | Error | 必須メソッド未実装 | _read/_write等を実装 |
| ERR_MULTIPLE_CALLBACK | Error | コールバック複数回呼び出し | コールバックは1回のみ |

### リトライ仕様

本機能自体にリトライ仕様はない。利用側で実装する。

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

本機能にトランザクション仕様はない。

## パフォーマンス要件

- highWaterMarkによるバッファサイズ制御
- objectModeではオブジェクト数でカウント
- pipe使用時の効率的なデータ転送

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

- 信頼できないソースからのストリームデータは検証が必要
- DoS防止のためhighWaterMarkの適切な設定
- AbortSignalによるキャンセル機能の活用

## 備考

- stream/promisesで Promise ベースの API が利用可能
- Web Streams API との相互運用性あり

---

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

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

### 推奨読解順序

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

ストリームの基本構造と状態管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | stream.js | `lib/stream.js` | エントリポイント、各ストリームクラスのエクスポート |
| 1-2 | internal/streams/legacy.js | `lib/internal/streams/legacy.js` | 基底Streamクラス |

**読解のコツ**: stream.jsは薄いラッパーで、実装は`internal/streams/`配下にある。

#### Step 2: Readableストリームを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | internal/streams/readable.js | `lib/internal/streams/readable.js` | Readableクラス実装 |

**主要処理フロー**:
1. **265-300行目**: ReadableState初期化
2. **push()**: データをバッファに追加
3. **read()**: バッファからデータを取得
4. **pipe()**: 他のストリームへ接続

#### Step 3: Writableストリームを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | internal/streams/writable.js | `lib/internal/streams/writable.js` | Writableクラス実装 |

**主要処理フロー**:
- WritableState初期化
- write(): データをバッファに書き込み
- end(): 書き込み終了
- drain イベント: バッファ空き通知

#### Step 4: Duplex/Transformを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | internal/streams/duplex.js | `lib/internal/streams/duplex.js` | Readable+Writable |
| 4-2 | internal/streams/transform.js | `lib/internal/streams/transform.js` | データ変換ストリーム |

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

```
stream (lib/stream.js)
    │
    ├─ Stream.Readable ─── internal/streams/readable.js
    │       │
    │       ├─ ReadableState
    │       ├─ push() / read() / pipe()
    │       └─ _read() [実装必須]
    │
    ├─ Stream.Writable ─── internal/streams/writable.js
    │       │
    │       ├─ WritableState
    │       ├─ write() / end()
    │       └─ _write() [実装必須]
    │
    ├─ Stream.Duplex ─── internal/streams/duplex.js
    │       └─ Readable + Writable
    │
    ├─ Stream.Transform ─── internal/streams/transform.js
    │       └─ _transform() [実装必須]
    │
    ├─ Stream.PassThrough ─── internal/streams/passthrough.js
    │
    ├─ pipeline ─── internal/streams/pipeline.js
    │
    └─ finished ─── internal/streams/end-of-stream.js
```

### データフロー図

```
[Readable]                [Transform]              [Writable]

データソース             データ変換              データシンク
    │                       │                       │
    ▼                       ▼                       ▼
 _read() ──▶ push() ──▶ pipe() ──▶ _transform() ──▶ pipe() ──▶ _write()
    │                       │                       │
    ▼                       ▼                       ▼
 'data'イベント         push(変換後)            'drain'イベント
    │                       │                       │
    ▼                       ▼                       ▼
 'end'イベント          'end'イベント           'finish'イベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| stream.js | `lib/stream.js` | ソース | メインエントリポイント |
| internal/streams/legacy.js | `lib/internal/streams/legacy.js` | ソース | 基底Streamクラス |
| internal/streams/readable.js | `lib/internal/streams/readable.js` | ソース | Readableストリーム |
| internal/streams/writable.js | `lib/internal/streams/writable.js` | ソース | Writableストリーム |
| internal/streams/duplex.js | `lib/internal/streams/duplex.js` | ソース | Duplexストリーム |
| internal/streams/transform.js | `lib/internal/streams/transform.js` | ソース | Transformストリーム |
| internal/streams/passthrough.js | `lib/internal/streams/passthrough.js` | ソース | PassThroughストリーム |
| internal/streams/pipeline.js | `lib/internal/streams/pipeline.js` | ソース | pipeline実装 |
| internal/streams/end-of-stream.js | `lib/internal/streams/end-of-stream.js` | ソース | finished実装 |
| internal/streams/destroy.js | `lib/internal/streams/destroy.js` | ソース | destroy処理 |
| internal/streams/state.js | `lib/internal/streams/state.js` | ソース | highWaterMark管理 |
| internal/streams/operators.js | `lib/internal/streams/operators.js` | ソース | ストリーム演算子 |
| stream/promises.js | `lib/stream/promises.js` | ソース | Promise版API |
