# バッチ設計書 4-tooling/generate-wasm-code.js

## 概要

本ドキュメントは、WASMコードの自動生成スクリプト `tooling/generate-wasm-code.js` の設計仕様を定義するものである。AssemblyScriptソース（xxhash64・md4）をコンパイルし、Base64エンコードされたWASMバイナリとしてJSファイルに埋め込む。

### 本バッチの処理概要

`tooling/generate-wasm-code.js` は、webpackで使用するハッシュ計算用のWebAssemblyモジュールを自動生成するためのスクリプトである。AssemblyScriptで記述されたハッシュアルゴリズムのソースコードをコンパイルし、生成されたWASMバイナリをBase64エンコードしてJavaScriptファイルに埋め込む形で出力する。

**業務上の目的・背景**：webpackはモジュールバンドリング時に大量のハッシュ計算を行う。xxhash64やmd4といったハッシュアルゴリズムをWebAssemblyで実装することで、JavaScript実装と比較して高速なハッシュ計算を実現する。AssemblyScriptを使用することで、TypeScriptライクな構文でWASMモジュールを開発でき、メンテナンス性を確保している。

**バッチの実行タイミング**：`lint:special` / `fix:special` のnpmスクリプトから実行される。CIパイプラインでのリントチェック時（変更検出モード）および開発時の修正モード（--writeオプション）で使用される。

**主要な処理内容**：
1. 対象ファイル（lib/util/hash/xxhash64.js、lib/util/hash/md4.js）を読み込む
2. `// #region wasm code: {identifier} ({name})` 〜 `// #endregion` で囲まれたWASMコード領域を正規表現で検出する
3. AssemblyScriptコンパイラ（asc）でソースをWASMバイナリにコンパイルする
4. コンパイルオプションとして速度最適化（-Ospeed）、アサーション無効化（--noAssert）、収束最適化（--converge）を使用
5. 生成されたWASMバイナリをBase64エンコードし、WebAssembly.Module初期化コードとしてJSファイルに埋め込む
6. 変更がある場合は --write オプションに応じてファイル書き込みまたは差分検出を行う

**前後の処理との関連**：`lint:special` スクリプトの一部として `generate-runtime-code.js` の後に実行される。`--write` なしで実行された場合はWASMコードが最新かどうかのチェックのみを行う。`fix:special` では `--write` 付きで実行される。

**影響範囲**：`lib/util/hash/xxhash64.js` と `lib/util/hash/md4.js` のWASMコード領域。生成されたWASMバイナリはwebpackのハッシュ計算パフォーマンスに直接影響する。

## バッチ種別

コード生成 / ビルドツール

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（lint:special / fix:special の一部として実行） |
| 実行時刻 | 任意 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動（npm run lint:special / npm run fix:special）またはCI/CD |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js 16以上 | Node.js 16以上が必要（コード内で明示的にチェック、ESM importにも必要） |
| assemblyscriptパッケージ | devDependencyとしてインストール済みであること |
| AssemblyScriptソース | xxhash64・md4のAssemblyScriptソースファイルが存在すること |

### 実行可否判定

Node.jsのメジャーバージョンが16未満の場合、エラーをスローして即座に終了する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --write | フラグ | No | false | ファイルへの書き込みを有効にする。指定しない場合はチェックモード |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| lib/util/hash/xxhash64.js | JavaScriptファイル | WASMコード埋め込み対象ファイル |
| lib/util/hash/md4.js | JavaScriptファイル | WASMコード埋め込み対象ファイル |
| AssemblyScriptソースファイル | AssemblyScript | 正規表現でキャプチャされたパス名のソースファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| lib/util/hash/xxhash64.js | JavaScriptファイル | --writeオプション指定時にWASMコード領域を更新 |
| lib/util/hash/md4.js | JavaScriptファイル | --writeオプション指定時にWASMコード領域を更新 |
| {sourcePathBase}.wasm | WASMバイナリ | コンパイル中間生成物 |
| {sourcePathBase}.wat | WATテキスト | コンパイル中間生成物（WASMテキスト形式） |
| 標準エラー出力（stderr） | テキスト | ファイル更新メッセージまたは更新必要メッセージ |
| process.exitCode | 数値 | 0: 変更なしまたは書き込み成功、1: チェックモードで差分検出 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | lib/util/hash/xxhash64.js、lib/util/hash/md4.js（既存ファイルの上書き更新） |
| 出力先 | プロジェクトルート相対 |
| 文字コード | UTF-8 |
| WASMバイナリ埋め込み形式 | Base64エンコード文字列 → Buffer.from(..., "base64") → WebAssembly.Module |

## 処理フロー

### 処理シーケンス

```
1. Node.jsバージョンチェック（16以上必須）
   └─ process.versions.nodeのメジャーバージョンを確認
2. AssemblyScriptコンパイラ（asc）のdynamic import
   └─ import("assemblyscript/asc") でESMモジュールとしてロード
3. 対象ファイルの読み込みとWASMコード領域の検出
   └─ 各ファイルをfs.readFileSyncでUTF-8テキストとして読み込み
   └─ 正規表現 /\n\/\/\s*#region wasm code: (.+) \((.+)\)(.*)\n[\s\S]+?\/\/[\s+]*#endregion\n/g でマッチ
   └─ identifier（変数名）、name（ソースファイル名）、flags（追加コンパイルフラグ）を抽出
4. AssemblyScriptコンパイル
   └─ asc.mainにコンパイルオプションを渡して実行
   └─ オプション: -Ospeed, --noAssert, --converge, --textFile, --outFile + カスタムフラグ
   └─ .wasmバイナリと.watテキストファイルを生成
5. WASMバイナリのBase64埋め込み
   └─ 生成された.wasmファイルを読み込み
   └─ Buffer.toString("base64")でBase64エンコード
   └─ WebAssembly.Module初期化コードとして整形
6. 差分判定・出力
   └─ 内容に変更がある場合：--write時はファイル書き込み、それ以外はexitCode=1
   └─ 内容に変更がない場合：何もしない
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{Node.js >= 16?}
    B -->|No| C[エラースロー]
    B -->|Yes| D[AssemblyScriptコンパイラをimport]
    D --> E[対象ファイル読み込み]
    E --> F[正規表現でWASMコード領域検出]
    F --> G{領域あり?}
    G -->|No| H[次のファイルへ / 処理終了]
    G -->|Yes| I[AssemblyScriptコンパイル実行]
    I --> J{コンパイル成功?}
    J -->|No| C
    J -->|Yes| K[WASMバイナリ読み込み]
    K --> L[Base64エンコード]
    L --> M[WebAssembly.Module初期化コード生成]
    M --> N{他の領域あり?}
    N -->|Yes| I
    N -->|No| O{内容に変更あり?}
    O -->|No| H
    O -->|Yes| P{--writeオプション?}
    P -->|Yes| Q[ファイル書き込み]
    P -->|No| R[exitCode=1で終了]
    Q --> H
```

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

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

本バッチはデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Error | Node.jsバージョン不足 | Node.js 16未満で実行 | Node.js 16以上にアップデート |
| Error | AssemblyScriptコンパイルエラー | ソースコードの構文エラーや型エラー | AssemblyScriptソースを修正 |
| exitCode=1 | 差分検出 | チェックモードで更新が必要な場合 | --writeオプション付きで再実行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（リトライ機構は未実装） |

### 障害時対応

コンパイルエラーが発生した場合は、AssemblyScriptソースファイルの構文を確認して修正する。assemblyscriptパッケージのバージョン互換性にも注意する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（データベース操作なし） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 2ファイル（xxhash64.js、md4.js）内のWASMコード領域 |
| 目標処理時間 | AssemblyScriptコンパイルを含め数秒〜十数秒 |
| メモリ使用量上限 | 特に制限なし（Node.jsデフォルト） |

## 排他制御

排他制御は行わない。コンパイル中間ファイル（.wasm、.wat）が同一パスに出力されるため、同時実行時は競合する可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 更新ログ | --writeモードでファイル更新時 | "{file} updated"（stderrに出力） |
| 差分検出ログ | チェックモードで差分検出時 | "{file} need to be updated"（stderrに出力） |
| コンパイルログ | AssemblyScriptコンパイル中 | stdout/stderrにコンパイラ出力を透過 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| N/A | N/A | N/A（監視設定は未実装） |

## 備考

- AssemblyScriptはESM形式でインポートされるため（dynamic import）、Node.js 16以上が必要
- コンパイルオプションの `-Ospeed` は速度最適化を優先するAssemblyScript固有のフラグ
- `--noAssert` はアサーションチェックを無効化し、WASMバイナリサイズを削減する
- `--converge` は複数パスの最適化を収束するまで繰り返す
- WASMバイナリサイズはコメントとしてJSファイルに記録される（`// {wasm.length} bytes`）
- 正規表現のマッチでフラグ（追加のコンパイルオプション）も抽出し、asc.mainに渡される
- コンパイル中間生成物（.wasm、.wat）はソースファイルと同じディレクトリに出力される
