アーキテクチャ
mooncake_impact_factor は、より大きなアプリケーションの中にある MoonBit モジュールです。MoonBit のパッケージがスコア規則と小さな JavaScript ヘルパーを定義し、Python がデータを構築し、Next.js アプリケーションがそれを SQLite から動的に、または静的ファイルとして配信します。このガイドはレジストリからブラウザーまでデータの流れを追い、各段階を担当するファイルを示します。
コンポーネント
| コンポーネント | パス | 言語 | 役割 |
|---|---|---|---|
score | src/score | MoonBit | スコア、ランク、モメンタムの規則(API)。 |
cli | src/cli | MoonBit (JS) | 他の言語向けにスコアスナップショットを計算するコマンド(API)。 |
static_search | src/static_search | MoonBit (JS) | 静的モードのバージョンタグとテキスト正規化(API)。 |
| インデックスビルダー | scripts/build_index.py | Python | レジストリを読み込み、SQLite データベースを書き出します。 |
| 静的エクスポーター | scripts/export_static_json.py | Python | データベースから public/data/** を書き出します。 |
| クエリ層 | lib/query.ts, lib/data.ts | TypeScript | クエリ AST、式パーサー、SQL へのコンパイル。 |
| Web アプリケーション | app, frontend/src | TypeScript | ページ、ルートハンドラー、静的検索ワーカー。 |
レジストリからスコアまで
scripts/build_index.py は実行のたびにデータベースを一から作り直します。
-
レジストリを読む。
~/.moon/registry/index/user以下のすべての*.indexファイルの各行が、公開された 1 つのバージョン(名前、バージョン、作成日時、メタデータ、依存関係)です。moon updateがこのローカルコピーを更新し、ランキングはちょうどそこに含まれるパッケージを対象とします。 -
最新バージョンを選ぶ。 各パッケージについて、作成日時、次にセマンティックバージョンで最新バージョンを選びます。そのバージョンの説明、キーワード、リポジトリ、ライセンスがパッケージの情報になります。
-
ダウンロード数を集める。
--skip-mooncakes-downloadsを指定しない限り、ビルダーはdata/download_cache.jsonにまだないパッケージごとにhttps://mooncakes.io/api/v0/manifest/<package>へ 8 スレッドで問い合わせ、結果をキャッシュに保存します。--downloads-jsonで個々のカウントを上書きできます。不明なカウントは0です。 -
エッジを作る。 スナップショット内の別のパッケージに依存するバージョンごとに、依存する側から依存される側へのパッケージ単位のエッジを記録します。自己依存は無視します。
first_seen_atは、依存する側でその依存関係を使った最も古いバージョンの作成日時です。 -
シグナルを数える。 ビルド時刻を とすると、パッケージのシグナルは次のとおりです。
シグナル 定義 dependentsこのパッケージに入るエッジの数。 recent_dependentsfirst_seen_at日のエッジ。downloads収集したダウンロード数。 days_since_release最新リリースから までの経過日数(整数)。日付が不明なら 3650。historical_dependentsfirst_seen_at日のエッジ。historical_recent_dependentsfirst_seen_atが 日に入るエッジ。historical_downloads常に 0。レジストリにはダウンロード履歴がありません。historical_days_since_release最新リリースから 30 日以上経っていれば days_since_release、そうでなければ0。過去のウィンドウは最近のウィンドウを 30 日前にずらしたものなので、2 つのスナップショットは同じ方法で計算されます。
-
スコアを付ける。 ビルダーはパッケージごとにこの 8 つのシグナルで
cliコマンドを実行し、返されたスナップショットをpackage_scoresテーブルに保存します。したがってスコア規則はsrc/scoreにしか存在しません。 -
テキストを索引化する。 SQLite の FTS5 テーブルが、全文検索のためにフルネーム、オーナー、パッケージ名、説明、キーワードを保持します。
データベースのテーブルは packages、versions、dependencies、package_edges、package_scores、search_index です。
配信
動的モード
MOONCAKE_DB_PATH を設定して npm run dev または npm run start を実行すると、データベースに基づくページと JSON のルートハンドラーが提供されます。
| ルート | 戻り値 |
|---|---|
GET /api/feeds/top?limit=<n> | スコアの降順、次に名前順に並べたパッケージ。 |
GET /api/feeds/hot?limit=<n> | 30 日間の成長量、スコア、名前の順に並べた Hot のパッケージ。 |
GET /api/feeds/rising?limit=<n> | Rising のパッケージ。並び順は hot と同じです。 |
GET /api/search?... | { "items": [...] }。パッケージ概要は最大 100 件。 |
GET /api/packages/<owner>/<package>/analysis | { "detail": ..., "dependents": [...] }. |
検索パラメーターは 入門ガイド に一覧があります。ast または expr パラメーターのクエリは SQL の WHERE 句にコンパイルされ、テキスト条件には FTS5 が使われます。
静的モード
npm run build:static-data はインデックスビルダーを実行したあと scripts/export_static_json.py を実行し、フィード、検索インデックス、パッケージごとのファイル、マニフェストを public/data に書き出します。npm run build:static は static_search をコンパイルし、NEXT_PUBLIC_APP_MODE=static で next build を実行して、ルートハンドラーなしでサイトを out/ にエクスポートします。ブラウザーではフィードとパッケージページは単なるファイル取得で、検索は Web Worker で動きます。詳しくは static_search の設計 を参照してください。deploy-static ワークフローがこのサイトを毎日再ビルドして公開します。
規則の置き場所
各規則の持ち主は 1 か所だけで、ほかはそれを呼び出します。
| 規則 | 持ち主 |
|---|---|
| スコア、ランク、モメンタム | src/score(src/cli 経由で呼び出し) |
| シグナルの定義と時間ウィンドウ | scripts/build_index.py |
| クエリ言語と AST | lib/query.ts |
| SQL へのコンパイルと動的な並び順 | lib/data.ts |
| 静的な評価と並び順 | frontend/src/static-search.worker.ts |
scripts/build_index.py には MoonBit の規則を写した Python 関数 compute_score と compute_momentum_label が残っていますが、ビルドでは呼び出されません。