アーキテクチャ

mooncake_impact_factor は、より大きなアプリケーションの中にある MoonBit モジュールです。MoonBit のパッケージがスコア規則と小さな JavaScript ヘルパーを定義し、Python がデータを構築し、Next.js アプリケーションがそれを SQLite から動的に、または静的ファイルとして配信します。このガイドはレジストリからブラウザーまでデータの流れを追い、各段階を担当するファイルを示します。

コンポーネント

コンポーネントパス言語役割
scoresrc/scoreMoonBitスコア、ランク、モメンタムの規則(API)。
clisrc/cliMoonBit (JS)他の言語向けにスコアスナップショットを計算するコマンド(API)。
static_searchsrc/static_searchMoonBit (JS)静的モードのバージョンタグとテキスト正規化(API)。
インデックスビルダーscripts/build_index.pyPythonレジストリを読み込み、SQLite データベースを書き出します。
静的エクスポーターscripts/export_static_json.pyPythonデータベースから public/data/** を書き出します。
クエリ層lib/query.ts, lib/data.tsTypeScriptクエリ AST、式パーサー、SQL へのコンパイル。
Web アプリケーションapp, frontend/srcTypeScriptページ、ルートハンドラー、静的検索ワーカー。

レジストリからスコアまで

scripts/build_index.py は実行のたびにデータベースを一から作り直します。

  1. レジストリを読む。 ~/.moon/registry/index/user 以下のすべての *.index ファイルの各行が、公開された 1 つのバージョン(名前、バージョン、作成日時、メタデータ、依存関係)です。moon update がこのローカルコピーを更新し、ランキングはちょうどそこに含まれるパッケージを対象とします。

  2. 最新バージョンを選ぶ。 各パッケージについて、作成日時、次にセマンティックバージョンで最新バージョンを選びます。そのバージョンの説明、キーワード、リポジトリ、ライセンスがパッケージの情報になります。

  3. ダウンロード数を集める。 --skip-mooncakes-downloads を指定しない限り、ビルダーは data/download_cache.json にまだないパッケージごとに https://mooncakes.io/api/v0/manifest/<package> へ 8 スレッドで問い合わせ、結果をキャッシュに保存します。--downloads-json で個々のカウントを上書きできます。不明なカウントは 0 です。

  4. エッジを作る。 スナップショット内の別のパッケージに依存するバージョンごとに、依存する側から依存される側へのパッケージ単位のエッジを記録します。自己依存は無視します。first_seen_at は、依存する側でその依存関係を使った最も古いバージョンの作成日時です。

  5. シグナルを数える。 ビルド時刻を τ\tau とすると、パッケージのシグナルは次のとおりです。

    シグナル定義
    dependentsこのパッケージに入るエッジの数。
    recent_dependentsfirst_seen_at ≥τ−180\ge \tau - 180 日のエッジ。
    downloads収集したダウンロード数。
    days_since_release最新リリースから τ\tau までの経過日数(整数)。日付が不明なら 3650。
    historical_dependentsfirst_seen_at ≤τ−30\le \tau - 30 日のエッジ。
    historical_recent_dependentsfirst_seen_at が [τ−210,τ−30][\tau - 210, \tau - 30] 日に入るエッジ。
    historical_downloads常に 0。レジストリにはダウンロード履歴がありません。
    historical_days_since_release最新リリースから 30 日以上経っていれば days_since_release −30- 30、そうでなければ 0。

    過去のウィンドウは最近のウィンドウを 30 日前にずらしたものなので、2 つのスナップショットは同じ方法で計算されます。

  6. スコアを付ける。 ビルダーはパッケージごとにこの 8 つのシグナルで cli コマンドを実行し、返されたスナップショットを package_scores テーブルに保存します。したがってスコア規則は src/score にしか存在しません。

  7. テキストを索引化する。 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
クエリ言語と ASTlib/query.ts
SQL へのコンパイルと動的な並び順lib/data.ts
静的な評価と並び順frontend/src/static-search.worker.ts

scripts/build_index.py には MoonBit の規則を写した Python 関数 compute_score と compute_momentum_label が残っていますが、ビルドでは呼び出されません。