はじめに

このガイドでは、チェックアウト直後の状態から、自分のランキングを載せた Web アプリケーションを動かすところまでを進め、その HTTP API への問い合わせ方を示します。対象はバージョン 0.1.2 です。各手順の中身は アーキテクチャガイド で説明しています。

前提条件

  • Python 3
  • moonc 0.10 以降の MoonBit ツールチェーン
  • Node.js 20.16、22.3 以降と npm
  • ~/.moon/registry/index/user にあるローカルの MoonBit レジストリスナップショット。moon update で作成・更新できます

1. データベースを構築する

パッケージを評価する cli コマンドをビルドしてから、mooncakes のダウンロード数をその場で取得する設定でデータベースを構築します。

moon update
moon build src/cli --target js
python3 scripts/build_index.py --db data/mooncake.db

このコマンドは次のことを行います。

  • ローカルレジストリ以下のすべての *.index レコードを読み込む
  • SQLite のスキーマを一から作り直す
  • 無効にしない限り、欠けているダウンロード数を mooncakes から取得する
  • パッケージのエッジ、逆依存の数、スコアスナップショット(MoonBit の cli コマンド経由)、FTS インデックスを計算する

mooncakes へのリクエストなしでビルドする場合:

python3 scripts/build_index.py --db data/mooncake.db --skip-mooncakes-downloads

ローカルのダウンロード数上書きファイルを適用する場合:

python3 scripts/build_index.py \
  --db data/mooncake.db \
  --downloads-json data/downloads.json

上書きファイルは、パッケージのフルネームをキーとする JSON オブジェクトでなければなりません。

{
  "owner/package": 1234
}

2. ローカルアプリを動かす

依存関係をインストールします。

npm install

フルスタックの Next.js アプリを起動します。

MOONCAKE_DB_PATH=data/mooncake.db npm run dev -- --hostname 127.0.0.1 --port 3000

その後 http://127.0.0.1:3000 を開きます。

アプリは現在、次のものを提供します。

  • /: ランキングされたパッケージを閲覧する UI
  • /search: メインの検索結果ページ
  • /advanced-search: 条件のグループ化とネイティブ式の編集ができるグラフィカルな詳細検索 UI
  • /api/*: SQLite に直接基づく JSON API

3. API に問い合わせる

検索:

GET /api/search?q=io&limit=20

対応する検索パラメーター:

  • ast: 詳細クエリビルダーが使う、グループ化されたクエリ AST をシリアライズしたもの
  • expr: 共通のクエリ AST にコンパイルされるネイティブのブール検索式
  • q: AND、OR、NOT、括弧、引用符付きフレーズ、および owner:、author:、package:、keyword:、description:、name: などのフィールド接頭辞を使える全体の全文検索クエリ
  • owner、package、keyword、description: AND で結合されるフィールド別の全文検索フィルター
  • license、repository: メタデータの部分文字列フィルター
  • rank: S, A, B, C, D
  • momentum: Rising, Hot, Stable
  • min_score, max_score
  • min_dependents, min_recent_dependents, min_downloads
  • from_year, to_year
  • has_repository、has_license: true または false
  • sort: relevance, score, growth, downloads, dependents, recent, updated, name
  • order: asc または desc
  • limit: 最大 100

フィールドの意味:

  • owner はローカルレジストリのメタデータにあるパッケージ名前空間のオーナーを指します。
  • author: は現在 owner: の別名にすぎません。
  • インデックスはまだ、作者リスト、メンテナーリスト、所属機関のフィールドを別に保持していません。

例:

GET /api/search?expr=(owner:gmlewis OR keyword:json) AND score>=180
GET /api/search?ast=<serialized-query-ast>
GET /api/search?q=owner:gmlewis AND "http client"&limit=20
GET /api/search?q=author:gmlewis AND keyword:json
GET /api/search?keyword=json&min_score=180&min_downloads=500&sort=downloads
GET /api/search?description=parser&from_year=2024&to_year=2026&has_repository=true&sort=updated
GET /api/search?rank=A&momentum=Rising&min_dependents=5&sort=growth

フィード:

GET /api/feeds/top?limit=50
GET /api/feeds/hot?limit=24
GET /api/feeds/rising?limit=24

パッケージ分析:

GET /api/packages/<owner>/<packageName>/analysis

4. 変更を検証する

moon fmt
moon check --target all
moon test --target js
moon test src/score --target all
python3 -m unittest scripts/build_index_test.py
npm run typecheck
npm run build
npm test

リポジトリのショートカット:

just build-db
just build-db-with-downloads data/downloads.json
just build-db-offline
just web-typecheck
just web-build
just serve
just dev

注意事項

  • SQLite データベースはインデックスのビルドごとに一から作り直されます。
  • ダウンロード数は mooncakes からのその場の応答、data/download_cache.json、またはローカルの上書きファイルから得られます。
  • sort=relevance で全文検索の条件が 1 つ以上あるとき、結果はまず SQLite の bm25 による関連度で並べられます。
  • 詳細クエリビルダーとネイティブの expr 入力は、どちらも同じ共通のクエリ AST 層を通してコンパイルされます。
  • 静的公開(npm run build:static-data、npm run build:static)については static_search チュートリアル で説明しています。