# 機能設計書 84-Archive

## 概要

本ドキュメントは、Bunランタイムにおけるアーカイブ操作機能（tar、gzip等）の設計を記述するものである。Archive APIはtarball形式のアーカイブファイルを作成・展開する機能を提供する。

### 本機能の処理概要

Archive機能は、複数のファイルを単一のtarballアーカイブにまとめたり、既存のアーカイブからファイルを展開する機能を提供する。gzip圧縮にも対応している。

**業務上の目的・背景**：ファイルのバンドリング、配布パッケージの作成、バックアップ、デプロイメントアーティファクトの生成など、複数ファイルを単一のアーカイブにまとめる必要性は多い。Bunネイティブでこの機能を提供することで、外部ツール（tar、gzipコマンド）への依存を排除し、クロスプラットフォームで統一したAPIを提供できる。

**機能の利用シーン**：
- npmパッケージのtar.gz形式での配布
- サーバーデプロイメント時のアーティファクト作成
- バックアップファイルの作成
- 複数アセットのバンドル配布
- ビルド成果物のアーカイブ化

**主要な処理内容**：
1. オブジェクトからtarballの構築（ファイルパス→コンテンツのマッピング）
2. 既存アーカイブデータの読み込み
3. gzip圧縮/展開
4. アーカイブのディスクへの書き込み
5. アーカイブからの個別ファイル展開
6. アーカイブ内容の列挙

**関連システム・外部連携**：libarchiveライブラリを使用してtar/gzip処理を実行。Blob.Storeによるメモリ管理。

**権限による制御**：ファイル書き込み時はファイルシステムへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | APIとして利用 |

## 機能種別

ファイル操作 / アーカイブ処理

## 入力仕様

### 入力パラメータ（constructor）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | object/Blob/ArrayBuffer | Yes | アーカイブ対象データ | 有効な形式であること |
| options.compress | string | No | 圧縮形式（"gzip"のみ対応） | "gzip"のみ |
| options.level | number | No | 圧縮レベル（1-12）| 1-12の範囲 |

### 入力パラメータ（Archive.write）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 出力ファイルパス | 有効なパス |
| data | Archive/object/Blob/ArrayBuffer | Yes | 書き込みデータ | 有効な形式 |
| options | object | No | 圧縮オプション | - |

### 入力データソース

- JavaScript オブジェクト（パス→コンテンツマッピング）
- Blobオブジェクト
- ArrayBuffer/TypedArray（既存アーカイブデータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Archive | Archive | Archiveオブジェクトインスタンス |
| Promise<void> | Promise | 書き込み完了通知 |
| contents | object | 展開されたファイル群 |

### 出力先

- Archiveオブジェクト（メモリ内）
- ファイルシステム（Archive.write時）

## 処理フロー

### 処理シーケンス

```
1. new Archive(data, options)の呼び出し
   └─ constructorでArchiveオブジェクト生成
2. 入力形式の判定
   ├─ Blob/ArrayBuffer → 既存アーカイブとして取り込み
   └─ Object → buildTarballFromObject()でtarball構築
3. 圧縮オプション処理
   └─ gzip指定時はレベル設定（デフォルト: 6）
4. Archive.write()でディスクに書き込み
   └─ startWriteTask()で非同期書き込み開始
5. 内容列挙/展開
   └─ countFilesInArchive()等でアーカイブ内容を処理
```

### フローチャート

```mermaid
flowchart TD
    A[new Archive] --> B{データ形式判定}
    B -->|Blob| C[store参照取得]
    B -->|ArrayBuffer| D[データコピー]
    B -->|Object| E[buildTarballFromObject]
    C --> F[createArchive]
    D --> F
    E --> F
    F --> G[Archiveオブジェクト]
    G --> H{操作選択}
    H -->|write| I[Archive.write]
    H -->|extract| J[展開処理]
    H -->|inspect| K[内容列挙]
    I --> L[startWriteTask]
    L --> M[非同期ディスク書き込み]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 圧縮形式 | gzipのみサポート | compress指定時 |
| BR-02 | 圧縮レベル | 1-12の範囲、デフォルト6 | level指定時 |
| BR-03 | tar形式 | PAX restricted形式を使用 | tarball作成時 |
| BR-04 | ゼロコピー | Blobからの参照時はコピーなし | Blob入力時 |

### 計算ロジック

圧縮レベルによりファイルサイズと処理速度のトレードオフが発生。レベル1は最速、レベル12は最大圧縮。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArguments | 引数エラー | 不正なデータ形式 | 入力形式を確認 |
| ArchiveFormatError | フォーマットエラー | tar形式設定失敗 | - |
| ArchiveOpenError | オープンエラー | アーカイブオープン失敗 | データを確認 |
| ArchiveWriteError | 書き込みエラー | データ書き込み失敗 | ディスク容量確認 |
| OutOfMemory | メモリエラー | メモリ不足 | データサイズを確認 |

### リトライ仕様

I/Oエラー時は自動リトライなし。

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

該当なし

## パフォーマンス要件

- libarchiveによる効率的な処理
- Blobからのゼロコピー参照
- 大規模ファイルのストリーム処理対応

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

- パストラバーサル攻撃への対策（展開時のパス検証）
- 圧縮爆弾への対策（展開サイズ制限）
- アーカイブ内の悪意あるファイル名への対策

## 備考

libarchive（bsd license）を使用してtar/gzip処理を実行。

---

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

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

### 推奨読解順序

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

Archive構造体の主要フィールドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Archive.zig | `src/bun.js/api/Archive.zig` | Archive構造体、Compression union |

**読解のコツ**:
- **9-15行目**: Compression union（none, gzip）の定義
- **17-20行目**: Archive構造体のフィールド（store, compress）
- **12-14行目**: gzip圧縮レベル（1-12、デフォルト6）

#### Step 2: コンストラクタを理解する

Archiveオブジェクト生成の流れを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Archive.zig | `src/bun.js/api/Archive.zig` | `constructor`関数 |

**主要処理フロー**:
1. **87-117行目**: constructor関数でデータ形式判定
2. **97-102行目**: Blobからのゼロコピー参照
3. **105-107行目**: ArrayBufferからのデータコピー
4. **111-113行目**: Objectからのtarball構築

#### Step 3: tarball構築処理を理解する

オブジェクトからtarballを生成する処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Archive.zig | `src/bun.js/api/Archive.zig` | `buildTarballFromObject`関数 |

**主要処理フロー**:
- **171-256行目**: buildTarballFromObject関数
- **183-199行目**: libarchive Archiveの設定
- **215-247行目**: プロパティイテレートとエントリ書き込み

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

```
new Archive() (JavaScript)
    │
    └─ Archive.constructor() (Zig, lines 87-117)
           │
           ├─ parseCompressionOptions() (lines 121-163)
           │
           ├─ Blobの場合 → store.ref() (lines 97-101)
           │
           ├─ ArrayBufferの場合 → dupe + createArchive() (lines 105-107)
           │
           └─ Objectの場合 → buildTarballFromObject() (lines 171-256)
                  │
                  ├─ libarchive.lib.Archive.writeNew()
                  ├─ writeSetFormatPaxRestricted()
                  ├─ JSPropertyIterator でプロパティ走査
                  └─ writeHeader/writeData/writeFinishEntry
```

### データフロー図

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

JavaScript Object ───▶ buildTarballFromObject ───▶ tarball bytes
{ path: content }      │
                       ├─ libarchive
                       └─ PAX format

tarball bytes    ───▶ gzip compression     ───▶ .tar.gz file
(optional)            (level 1-12)

Archive          ───▶ Archive.write        ───▶ ファイルシステム
                      startWriteTask
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Archive.zig | `src/bun.js/api/Archive.zig` | ソース | Archive APIのメイン実装 |
| Archive.classes.ts | `src/bun.js/api/Archive.classes.ts` | コード生成 | JSクラス定義 |
| libarchive.zig | `src/bun.js/` | ソース | libarchiveラッパー |
