# 画面設計書 5-JSStorageデモ

## 概要

本ドキュメントは、localStorage/sessionStorageを使用したkey-value VFSの永続化デモ（demo-jsstorage.html）の画面設計書です。

### 本画面の処理概要

この画面は、SQLite WASMのkvvfs（Key-Value Virtual File System）を使用して、ブラウザのlocalStorageまたはsessionStorageにデータベースを永続化するデモンストレーションを提供します。

**業務上の目的・背景**：Webアプリケーションでデータを永続化する際、従来のインメモリデータベースではページリロード時にデータが失われます。kvvfsを使用することで、ブラウザのlocalStorage/sessionStorageにデータベースを保存し、セッションをまたいでデータを永続化できます。これはOPFSが利用できない環境でのフォールバック手段としても有用です。

**画面へのアクセス方法**：HTTPサーバー経由で `demo-jsstorage.html` にアクセスします。jswasm/sqlite3.jsとdemo-jsstorage.jsを読み込みます。

**主要な操作・処理内容**：
1. kvvfs VFSを使用したDB初期化 - `new oo.JsStorageDb(dbStorage)` でストレージバックエンドを指定
2. ストレージクリア - ボタンクリックで `db.clearStorage()` を実行
3. DB初期化 - テーブル作成とサンプルデータ挿入
4. データ検索 - SELECT文でDBからデータを取得して表示
5. ストレージサイズ確認 - `db.storageSize()` でおおよそのサイズを取得

**画面遷移**：
- 遷移先画面：なし
- 遷移元画面：index.html、index-dist.html

**権限による表示制御**：なし

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | SQLiteライブラリ初期化 | 主機能 | kvvfs対応sqlite3モジュール初期化 |
| 2 | データベース接続管理 | 主機能 | kvvfs VFSでのDB作成・接続 |
| 43 | OS抽象化層（VFS） | 主機能 | kvvfs VFSによるlocalStorage/sessionStorage永続化 |
| 6 | SELECT文処理 | 補助機能 | 永続化DBへのクエリ実行 |
| 7 | INSERT文処理 | 補助機能 | 永続化DBへのデータ挿入 |

## 画面種別

デモ（対話型）

## URL/ルーティング

`ext/wasm/demo-jsstorage.html`

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| Clear logボタン | 入力 | クリックイベント | ログ出力エリアをクリア |
| Clear storageボタン | 入力 | クリックイベント | ストレージ内のDBデータをクリア |
| (Re)init dbボタン | 入力 | クリックイベント | DBテーブルを再作成してサンプルデータ挿入 |
| Select db rowsボタン | 入力 | クリックイベント | DBからデータを取得して表示 |
| Approx. storage sizeボタン | 入力 | クリックイベント | ストレージのおおよそのサイズを表示 |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| タイトルバー | ヘッダー | "sqlite3-kvvfs.js tests" |
| 初期化スピナー | 中央 | WASM初期化中に表示 |
| オプションフィールドセット | 上部 | 各種操作ボタン群 |
| ログ出力エリア | 下部 | 操作結果のログ表示 |

## イベント仕様

### 1-ページロード（初期化）

**トリガー**: ページロード完了時

**処理内容**:
1. **行111**: `sqlite3InitModule(globalThis.sqlite3TestModule)` でWASM初期化
2. **行112**: `runTests(sqlite3)` を呼び出し
3. **行49-53**: kvvfs VFSの存在確認
4. **行55-57**: `new oo.JsStorageDb(dbStorage)` でDB作成

**結果**:
- kvvfs非対応ビルドの場合はエラー表示
- 前回セッションのデータが存在する場合はその旨を表示

### 2-Clear logボタンクリック

**トリガー**: btn-clear-log ボタンクリック

**処理内容**:
```javascript
document.querySelector('#btn-clear-log').addEventListener('click',function(){
  eOutput.innerText = '';
});
```

**行番号**: 64-66

### 3-Clear storageボタンクリック

**トリガー**: btn-clear-storage ボタンクリック

**処理内容**:
```javascript
document.querySelector('#btn-clear-storage').addEventListener('click',function(){
  const sz = db.clearStorage();
  log("kvvfs",db.filename+"Storage cleared:",sz,"entries.");
});
```

**行番号**: 60-63

**データベース操作**: ストレージ内のすべてのDBデータを削除

### 4-(Re)init dbボタンクリック

**トリガー**: btn-init-db ボタンクリック

**処理内容**:
```javascript
db.exec({
  sql: ["drop table if exists t;",
        "create table if not exists t(a);",
        "insert into t(a) values(?),(?),(?)"],
  bind: [performance.now() >> 0,
         (performance.now() * 2) >> 0,
         (performance.now() / 2) >> 0],
  saveSql
});
```

**行番号**: 67-84

**データベース操作**:
- DROP TABLE t
- CREATE TABLE t(a)
- INSERT 3行（performance.now()ベースの値）

### 5-Select db rowsボタンクリック

**トリガー**: btn-select1 ボタンクリック

**処理内容**:
```javascript
db.exec({
  sql: "select * from t order by a",
  rowMode: 0,
  callback: (v)=>log(v)
});
```

**行番号**: 85-97

**データベース操作**: SELECT * FROM t ORDER BY a

### 6-Approx. storage sizeボタンクリック

**トリガー**: btn-storage-size ボタンクリック

**処理内容**:
```javascript
log("size.storageSize(",dbStorage,") says", db.storageSize(), "bytes");
```

**行番号**: 98-101

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Clear storage | 全体 | DELETE | ストレージ内のすべてのデータを削除 |
| (Re)init db | t | DROP/CREATE/INSERT | テーブル再作成とサンプルデータ挿入 |
| Select db rows | t | SELECT | 全行取得 |

### テーブル別更新項目詳細

#### テーブル t

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | a | performance.now() >> 0 | 現在時刻のミリ秒（整数） |
| INSERT | a | (performance.now() * 2) >> 0 | 現在時刻の2倍 |
| INSERT | a | (performance.now() / 2) >> 0 | 現在時刻の半分 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| LOG-001 | 情報 | "Loaded module: X.X.X" | 初期化完了時 |
| ERR-001 | エラー | "This build is not kvvfs-capable." | kvvfs非対応ビルド時 |
| LOG-002 | 情報 | "db.storageSize(): X" | 初期化時 |
| LOG-003 | 情報 | "kvvfs {filename}Storage cleared: X entries." | ストレージクリア時 |
| LOG-004 | 情報 | "DB (re)initialized." | DB初期化完了時 |
| LOG-005 | 情報 | "Storage backend: {filename}" | 初期化時 |
| LOG-006 | 情報 | "DB is empty. Use the init button to populate it." | DB空の場合 |
| LOG-007 | 情報 | "DB contains data from a previous session." | 前回データ存在時 |

## 例外処理

| 例外状況 | 対応処理 |
|---------|----------|
| kvvfs非対応ビルド | error()でエラーメッセージ表示、処理中断 |
| DB操作エラー | try-catchでエラーメッセージを表示 |

## 備考

- デフォルトでlocalStorageを使用（行55: `const dbStorage = 0 ? 'session' : 'local'`）
- sessionStorageを使用する場合はコード変更が必要
- ストレージ容量制限（通常5-10MB）に注意
- kvvfs v2（late 2025）ではtransient storageも利用可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | demo-jsstorage.js | `ext/wasm/demo-jsstorage.js` | JsStorageDbクラスの使用方法 |

**読解のコツ**:
- `oo.JsStorageDb` はkvvfs VFSを使用するDB接続クラス
- `db.storageSize()` でストレージ使用量を取得
- `db.clearStorage()` でストレージをクリア

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | demo-jsstorage.html | `ext/wasm/demo-jsstorage.html` | HTML構造とスクリプト読み込み |
| 2-2 | demo-jsstorage.js | `ext/wasm/demo-jsstorage.js` | 即時関数と初期化処理 |

**主要処理フロー**:
1. **行45**: jswasm/sqlite3.js読み込み
2. **行46**: common/SqliteTestUtil.js読み込み
3. **行47**: demo-jsstorage.js読み込み
4. **行111-113**: sqlite3InitModule()後にrunTests()実行

#### Step 3: kvvfs VFS初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | demo-jsstorage.js | `ext/wasm/demo-jsstorage.js` | runTests()関数内のVFS確認とDB作成 |

**主要処理フロー**:
- **行49-53**: `capi.sqlite3_vfs_find('kvvfs')` でVFS存在確認
- **行55-56**: dbStorage変数で'local'または'session'を指定
- **行57**: `new oo.JsStorageDb(dbStorage)` でDB作成

#### Step 4: イベントハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | demo-jsstorage.js | `ext/wasm/demo-jsstorage.js` | 各ボタンのイベントハンドラ |

**主要処理フロー**:
- **行60-63**: Clear storageボタン - `db.clearStorage()`
- **行64-66**: Clear logボタン - `eOutput.innerText = ''`
- **行67-84**: (Re)init dbボタン - DROP/CREATE/INSERT実行
- **行85-97**: Select db rowsボタン - SELECT実行
- **行98-101**: Approx. storage sizeボタン - `db.storageSize()`

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

```
demo-jsstorage.html (ページロード)
    │
    ├─ sqlite3.js (WASMローダー)
    ├─ SqliteTestUtil.js (テストユーティリティ)
    │
    └─ demo-jsstorage.js
           │
           ├─ sqlite3InitModule()
           │      └─ runTests(sqlite3)
           │             ├─ capi.sqlite3_vfs_find('kvvfs')
           │             ├─ new oo.JsStorageDb(dbStorage)
           │             └─ イベントハンドラ登録
           │
           └─ ボタンクリック時
                  ├─ db.clearStorage()
                  ├─ db.exec() (DDL/DML)
                  ├─ db.exec() (SELECT)
                  └─ db.storageSize()
```

### データフロー図

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

ページロード ───▶ sqlite3InitModule() ───▶ sqlite3オブジェクト
                        │
                        └───▶ new JsStorageDb()
                                    │
                                    ▼
                              kvvfs VFS初期化
                                    │
                        ┌───────────┼───────────┐
                        │           │           │
                   localStorage  sessionStorage  (選択)
                        │           │
                        ▼           ▼
                      永続化ストレージ

ボタンクリック ───▶ db.exec() / db.clearStorage() ───▶ ストレージ更新
                                                            │
                                                            ▼
                                                      ログ出力表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| demo-jsstorage.html | `ext/wasm/demo-jsstorage.html` | テンプレート | デモページHTML |
| demo-jsstorage.js | `ext/wasm/demo-jsstorage.js` | ソース | kvvfsデモロジック |
| SqliteTestUtil.js | `ext/wasm/common/SqliteTestUtil.js` | ソース | テストユーティリティ |
| sqlite3.js | `ext/wasm/jswasm/sqlite3.js` | ソース | WASM初期化ローダー |
| emscripten.css | `ext/wasm/common/emscripten.css` | スタイル | Emscripten共通スタイル |
| testing.css | `ext/wasm/common/testing.css` | スタイル | テストページ共通スタイル |
