尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗青空文庫に収録された、著作権の消滅した作品の全文から任意のワードを検索し、その用例・文脈を表示するサービスです。インデックス済みの作品数・段落数はアプリ画面にリアルタイムで表示されます。
ブラウザ
↓
Next.js App Router(React 19 + Tailwind CSS 4)
├─ app/page.tsx + components/* ...... UI(クライアントコンポーネント)
└─ app/api/{search,stats}/route.ts ... Route Handlers(サーバー)
↓ @libsql/client
Turso(libSQL)— SQLite FTS5 + trigramトークナイザー
file: URLでSQLiteファイルをそのまま利用できるため、Tursoアカウントなしでも動作確認可能前提: Node.js 22以上(CIで使用しているバージョン)
npm install
目録CSVを青空文庫本家から、本文をGitHubミラー(aozorahack/aozorabunko_text)からダウンロードし、ローカルのSQLiteファイル(既定 data/aozora.db)にFTS5インデックスを構築します。目録の取得元は環境変数 CATALOG_URL で差し替えられます。
# 著作権の消滅した全作品をインデックス
npm run index
# テスト用: 最初の100作品だけ
npm run index -- --limit 100
# 中断から再開(インデックス済みの作品をスキップ)
npm run index -- --resume
環境変数で保存先を変更できます: DATA_DIR(ダウンロードファイルの格納先、既定 ./data)、DB_PATH(SQLiteファイルの出力先、既定 <DATA_DIR>/aozora.db)。
再インデックスが必要になる変更: 本文の整形規則(入力者注や凡例ブロックの除去、段落の分割、 改行の扱い)や、目録から取り込む項目(作家別作品リストのURLなど)を変えた場合、 既存のインデックスには反映されないため作り直しが必要です。 作り直すまでは、その項目を使う表示(作家名のリンクなど)が出ないだけで、検索自体は動きます。 整形規則は テスト仕様書 §2・§3 にまとまっています。 ローカルで作り直さずに Reindex ワークフローを使うこともできます。
ローカル環境なしでインデックスを作り直せます。Actions の Reindex ワークフローを手動実行すると、 全件インデックスを構築し、Turso に新しいデータベースとして取り込みます。
| 入力 | 内容 |
|---|---|
db_name | Turso のデータベース名(空なら aozora-YYYYMMDD) |
limit | 先頭 N 作品だけ構築(空なら全件・20〜60分) |
resume | 前回の中断地点から再開する |
skip_upload | 構築と検証だけ行い、Turso には取り込まない |
実行前にリポジトリシークレット TURSO_API_TOKEN(Turso のプラットフォームトークン。
データベーストークンではありません)を登録してください。
動作中の本番環境は影響を受けません。Vercel の環境変数を手で新しいデータベースに向けるまで、 アプリは旧データベースを参照し続けます。失敗した構築が本番に出ることはなく、 旧データベースはロールバック用にそのまま残ります。切り替え手順は実行結果のサマリに表示されます。
Turso は既存データベースの上書きに対応していないため、実行のたびに別名のデータベースが作られます。
切り替えを確認したら、旧データベースは turso db destroy <旧名> で削除してください。
認証トークンはワークフローでは発行も出力もしません。このリポジトリは public で、 ジョブログ・サマリ・artifact は誰でも閲覧できるためです。トークンは Turso ダッシュボードから発行してください。
ローカルのSQLiteファイルをそのまま使う場合(Tursoアカウント不要):
TURSO_DATABASE_URL=file:./data/aozora.db npm run dev
Tursoにホストする場合は、作成したSQLiteファイルをTursoデータベースへ取り込みます(ファイルサイズ上限2GB)。
turso db create aozora --from-file data/aozora.db
turso db show aozora --url
turso db tokens create aozora
# .env.local
TURSO_DATABASE_URL=libsql://<取得したURL>
TURSO_AUTH_TOKEN=<取得したトークン>
npm run dev # 開発サーバー
npm run build && npm run start # 本番ビルド・起動
ブラウザで http://localhost:3000 を開く。
| コマンド | 内容 |
|---|---|
npm run dev | 開発サーバー起動 |
npm run build | 本番ビルド |
npm run start | 本番サーバー起動 |
npm test | テスト実行(Vitest) |
npm run test:watch | テストのウォッチ実行 |
npm run test:coverage | カバレッジ付きでテスト実行 |
npm run index | インデクサー実行(scripts/build-index.ts) |
/ に置き換えて1行にまとめ、400文字を超える段落は分割stale-while-revalidateで最大7日間)このプロジェクトはテスト駆動で開発します。先に テスト仕様書 の表を書き、
それからテストと実装を書くという順序です。テスト名の先頭には仕様書の項目 ID
(AZ-02、API-09 など)が入っているので、失敗したテストから仕様書の該当行を引けます。
npm test # 全件実行
npm run test:watch # ウォッチ実行
npm run test:coverage # カバレッジ付き
// @vitest-environment jsdom で切り替えますlib/db.ts のテストはモックせず、一時ファイル上に本物の SQLite + FTS5(trigram) を作って検証しますimport して NextRequest を渡すため、サーバー起動は不要ですGitHub Actions(.github/workflows/ci.yml)で以下を実行:
tsc --noEmit)、npm test、本番ビルド/api/stats と /api/search
の応答、および2文字以下のクエリが400で拒否されることを確認青空文庫 — 著作権の消滅した作品を公開するデジタル図書館。 インデックス作成時は、目録を青空文庫本家から、本文をGitHubミラー(aozorahack/aozorabunko_text)からダウンロードします。