# 機能設計書: node:zlib - 圧縮・解凍

## 1. 機能概要

### 1.1 機能名
node:zlib - 圧縮・解凍

### 1.2 機能ID
100

### 1.3 概要説明
BunにおけるNode.js互換のzlibモジュール実装。Gzip, Deflate, Brotli, Zstd等の圧縮アルゴリズムを使用したデータの圧縮・解凍機能を提供する。ストリームベースのAPIとワンショット（同期/非同期）APIの両方をサポートし、HTTPレスポンス圧縮やファイル圧縮など幅広い用途に対応する。Zigで実装されたネイティブ圧縮エンジンにより高速な処理を実現する。

### 1.4 関連画面/API
- CLI: `bun run`コマンドで圧縮・解凍アプリケーションを実行
- API: `require("node:zlib")`

## 2. 機能要件

### 2.1 ユースケース

#### UC-100-1: Gzip圧縮/解凍
- **アクター**: 開発者
- **事前条件**: 圧縮/解凍対象のデータがある
- **基本フロー**:
  1. `zlib.gzip(buffer, callback)`で圧縮
  2. `zlib.gunzip(buffer, callback)`で解凍
- **事後条件**: データが圧縮/解凍される

#### UC-100-2: ストリーム圧縮
- **アクター**: 開発者
- **事前条件**: 入力ストリームと出力先がある
- **基本フロー**:
  1. `zlib.createGzip()`でTransformストリーム作成
  2. `input.pipe(gzip).pipe(output)`でパイプライン構築
- **事後条件**: ストリームデータが圧縮される

#### UC-100-3: Brotli圧縮
- **アクター**: 開発者
- **事前条件**: Brotli圧縮対象のデータがある
- **基本フロー**:
  1. `zlib.brotliCompress(buffer, callback)`で圧縮
  2. `zlib.brotliDecompress(buffer, callback)`で解凍
- **事後条件**: Brotli形式で圧縮/解凍される

### 2.2 機能仕様

#### 2.2.1 圧縮ストリームクラス
| クラス | 説明 |
|--------|------|
| `Gzip` | Gzip圧縮ストリーム |
| `Gunzip` | Gzip解凍ストリーム |
| `Deflate` | Deflate圧縮ストリーム |
| `Inflate` | Deflate解凍ストリーム |
| `DeflateRaw` | 生Deflate圧縮ストリーム |
| `InflateRaw` | 生Deflate解凍ストリーム |
| `Unzip` | 自動検出解凍ストリーム |
| `BrotliCompress` | Brotli圧縮ストリーム |
| `BrotliDecompress` | Brotli解凍ストリーム |
| `ZstdCompress` | Zstd圧縮ストリーム |
| `ZstdDecompress` | Zstd解凍ストリーム |

#### 2.2.2 ワンショット非同期API
| 関数 | 説明 |
|------|------|
| `gzip(buffer[, options], callback)` | Gzip圧縮 |
| `gunzip(buffer[, options], callback)` | Gzip解凍 |
| `deflate(buffer[, options], callback)` | Deflate圧縮 |
| `inflate(buffer[, options], callback)` | Deflate解凍 |
| `deflateRaw(buffer[, options], callback)` | 生Deflate圧縮 |
| `inflateRaw(buffer[, options], callback)` | 生Deflate解凍 |
| `unzip(buffer[, options], callback)` | 自動検出解凍 |
| `brotliCompress(buffer[, options], callback)` | Brotli圧縮 |
| `brotliDecompress(buffer[, options], callback)` | Brotli解凍 |

#### 2.2.3 ワンショット同期API
| 関数 | 説明 |
|------|------|
| `gzipSync(buffer[, options])` | 同期Gzip圧縮 |
| `gunzipSync(buffer[, options])` | 同期Gzip解凍 |
| `deflateSync(buffer[, options])` | 同期Deflate圧縮 |
| `inflateSync(buffer[, options])` | 同期Deflate解凍 |
| `brotliCompressSync(buffer[, options])` | 同期Brotli圧縮 |
| `brotliDecompressSync(buffer[, options])` | 同期Brotli解凍 |

#### 2.2.4 圧縮オプション
| オプション | 説明 |
|-----------|------|
| `flush` | フラッシュモード |
| `finishFlush` | 終了時フラッシュモード |
| `chunkSize` | 出力バッファサイズ |
| `windowBits` | ウィンドウサイズ |
| `level` | 圧縮レベル (0-9) |
| `memLevel` | メモリ使用量 (1-9) |
| `strategy` | 圧縮戦略 |
| `dictionary` | 圧縮辞書 |
| `info` | メタ情報返却 |
| `maxOutputLength` | 最大出力サイズ |

#### 2.2.5 ユーティリティ
| 関数/定数 | 説明 |
|----------|------|
| `crc32(data[, value])` | CRC32チェックサム計算 |
| `constants` | zlib定数オブジェクト |

## 3. 技術設計

### 3.1 アーキテクチャ

```
┌─────────────────────────────────────────────────────────────┐
│                    JavaScript Layer                          │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  node:zlib (src/js/node/zlib.ts)                        ││
│  │  ┌───────────────────────────────────────────────────┐  ││
│  │  │  ZlibBase (extends Transform)                     │  ││
│  │  │  - _transform(), _flush(), _destroy()             │  ││
│  │  └───────────────────────────────────────────────────┘  ││
│  │  ┌───────────────────────────────────────────────────┐  ││
│  │  │  Gzip, Gunzip, Deflate, Inflate, etc.             │  ││
│  │  │  BrotliCompress, BrotliDecompress                 │  ││
│  │  │  ZstdCompress, ZstdDecompress                     │  ││
│  │  └───────────────────────────────────────────────────┘  ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
                            │
┌───────────────────────────▼─────────────────────────────────┐
│                     Native Layer                             │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  node_zlib_binding.zig                                   ││
│  │  ┌───────────────────────────────────────────────────┐  ││
│  │  │  crc32() - CRC32計算                              │  ││
│  │  │  CompressionStream<T> - 圧縮ストリームテンプレート│  ││
│  │  │  NativeZlib, NativeBrotli, NativeZstd             │  ││
│  │  └───────────────────────────────────────────────────┘  ││
│  └─────────────────────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────────────────────┐│
│  │  bun.zlib - 圧縮ライブラリバインディング                ││
│  │  - zlib (deflate/inflate)                               ││
│  │  - brotli                                                ││
│  │  - zstd                                                  ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
```

### 3.2 クラス構成

```
zlib
├── Base Classes
│   └── ZlibBase (extends Transform)
│       ├── _transform(chunk, encoding, callback)
│       ├── _flush(callback)
│       ├── _destroy(error, callback)
│       ├── flush([kind,] callback)
│       ├── close([callback])
│       └── reset()
├── Zlib Streams
│   ├── Gzip / Gunzip
│   ├── Deflate / Inflate
│   ├── DeflateRaw / InflateRaw
│   └── Unzip
├── Brotli Streams
│   ├── BrotliCompress
│   └── BrotliDecompress
├── Zstd Streams
│   ├── ZstdCompress
│   └── ZstdDecompress
├── Factory Functions
│   ├── createGzip(), createGunzip()
│   ├── createDeflate(), createInflate()
│   ├── createDeflateRaw(), createInflateRaw()
│   ├── createUnzip()
│   ├── createBrotliCompress(), createBrotliDecompress()
│   └── createZstdCompress(), createZstdDecompress()
├── One-shot Functions
│   ├── Async: gzip, gunzip, deflate, inflate, etc.
│   └── Sync: gzipSync, gunzipSync, deflateSync, inflateSync, etc.
├── Utilities
│   └── crc32(data, value)
└── Constants
    ├── Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, etc.
    ├── Z_DEFAULT_COMPRESSION, Z_BEST_SPEED, Z_BEST_COMPRESSION
    ├── BROTLI_OPERATION_*, BROTLI_PARAM_*
    └── ZSTD_e_*, ZSTD_c_*, etc.
```

### 3.3 処理フロー

#### ストリーム圧縮フロー
```
1. createGzip(options)
   └── new Gzip(options)
       └── ZlibBase.call(this, options, mode, handle)
           ├── Transform.call(this, options)
           ├── NativeZlib ハンドル取得
           └── 初期設定

2. gzip._transform(chunk, encoding, callback)
   ├── processChunk(this, chunk, flushFlag, callback)
   │   └── handle.write(flush, in, in_off, in_len, out, out_off, out_len)
   └── [native] 圧縮処理
       └── bun.zlib.deflate()

3. gzip._flush(callback)
   └── this._transform(Buffer.alloc(0), '', callback)
       └── Z_FINISH フラグで最終処理

4. processCallback()
   ├── 出力データをpush()
   ├── バッファ不足時は継続処理
   └── callback()
```

#### 同期圧縮フロー
```
1. gzipSync(buffer, options)
   └── zlibBufferSync(engine, buffer)
       └── processChunkSync(engine, buffer, finishFlushFlag)
           └── handle.writeSync(...)
               └── [native] 同期圧縮
```

#### crc32計算フロー
```
1. zlib.crc32(data, value)
   └── [native] node_zlib_binding.crc32
       ├── data バリデーション
       ├── value バリデーション (0-4294967295)
       └── bun.zlib.crc32(value, slice)
```

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

### 4.1 推奨読解順序

1. **定数とインポート** (`src/js/node/zlib.ts`)
   - **1-46行目**: 定数インポート、NativeZlib等のZig関数
   - **32-46行目**: process.binding('constants').zlibから圧縮定数取得

2. **ZlibBase クラス** (`src/js/node/zlib.ts`)
   - **145-200行目**: ZlibBaseコンストラクタ
   - highWaterMark, flush, finishFlush設定
   - **225-229行目**: reset()メソッド
   - **231-234行目**: _flush()メソッド
   - **290-308行目**: _transform()メソッド

3. **processChunk関数**
   - **398-418行目**: processChunk（非同期処理）
   - **310-396行目**: processChunkSync（同期処理）
   - handle.write/writeSync呼び出し

4. **ネイティブ実装** (`src/bun.js/node/node_zlib_binding.zig`)
   - **3-48行目**: crc32関数実装
   - **50-279行目**: CompressionStream<T>テンプレート
   - **52-110行目**: write関数（非同期）
   - **158-213行目**: writeSync関数（同期）

5. **CompressionStreamのwrite処理**
   - **97-107行目**: WorkPoolへのタスク投入
   - **112-126行目**: AsyncJob.run（バックグラウンド処理）
   - **128-156行目**: runFromJSThread（結果コールバック）

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

```
zlib.createGzip(options)
├── new Gzip(options)
│   └── ZlibBase.call(this, options, GZIP, handle)
│       ├── Transform.call(this, options)
│       ├── handle = NativeZlib
│       └── _outBuffer = Buffer.allocUnsafe(chunkSize)
└── return gzip

gzip._transform(chunk, encoding, callback)
├── maxFlush(flushFlag, _finishFlushFlag)
└── processChunk(this, chunk, flushFlag, callback)
    └── handle.write(flush, in, in_off, in_len, out, out_off, out_len)
        └── [native] CompressionStream.write()
            ├── this.stream.setBuffers(in, out)
            ├── this.stream.setFlush(flush)
            └── jsc.WorkPool.schedule(&this.task)
                └── AsyncJob.run()
                    └── this.stream.doWork()
                        └── bun.zlib圧縮処理

zlib.crc32(data, value)
└── [native] node_zlib_binding.crc32()
    ├── data バリデーション
    ├── value バリデーション
    └── bun.zlib.crc32(value, slice)
```

### 4.3 データフロー図

```
[Stream Compression]
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Input Data  │────>│ ZlibBase    │────>│ Compressed  │
│ (Buffer)    │     │ _transform  │     │ Data        │
└─────────────┘     └──────┬──────┘     └─────────────┘
                           │
                    ┌──────▼──────┐
                    │ Native      │
                    │ handle.write│
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ WorkPool    │
                    │ Async Task  │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ bun.zlib    │
                    │ compress    │
                    └─────────────┘


[One-shot Compression]
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Input Data  │────>│ zlibBuffer  │────>│ Compressed  │
│ (Buffer)    │     │ (engine)    │     │ Data        │
└─────────────┘     └──────┬──────┘     └─────────────┘
                           │
                    ┌──────▼──────┐
                    │ stream.on   │
                    │ ('data')    │
                    │ ('end')     │
                    └─────────────┘
```

### 4.4 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| `src/js/node/zlib.ts` | TypeScript | node:zlibモジュールのメイン実装 |
| `src/bun.js/node/node_zlib_binding.zig` | Zig | crc32, CompressionStream実装（341行） |
| `src/js/node/stream.ts` | TypeScript | Transform基底クラス |
| `src/js/internal/validators.ts` | TypeScript | パラメータ検証 |

## 5. 設計上の考慮事項

### 5.1 Node.js互換性
- Node.jsのzlib APIと完全互換を目指す
- 全圧縮アルゴリズムのサポート（Gzip, Deflate, Brotli, Zstd）
- ストリームAPIとワンショットAPIの両方を提供

### 5.2 パフォーマンス最適化
- Zigネイティブ実装による高速圧縮
- WorkPoolによる非同期処理のバックグラウンド実行
- 効率的なバッファ管理（_outBuffer再利用）

### 5.3 メモリ管理
- maxOutputLengthによる出力サイズ制限
- chunkSizeによるバッファサイズ制御
- 適切なストリーム破棄（_destroy）

### 5.4 エラーハンドリング
- zlibOnErrorによるエラーコールバック
- checkError()によるエラー検出
- 圧縮エラーコードの適切な伝播

## 6. テスト方針

### 6.1 単体テスト
- 各圧縮アルゴリズムの圧縮/解凍テスト
- オプション（level, windowBits等）のテスト
- crc32計算の正確性テスト

### 6.2 統合テスト
- ストリームパイプラインでの圧縮テスト
- HTTPレスポンス圧縮テスト
- 大容量データの圧縮テスト

### 6.3 互換性テスト
- Node.jsのzlibテストスイートの実行
- 他の圧縮ツールとの相互運用テスト

## 7. 変更履歴

| 日付 | バージョン | 変更内容 |
|------|-----------|---------|
| 2026-01-27 | 1.0 | 初版作成 |
