コンテンツにスキップ
hsblabs OSS

Scraping KDL は処理を二つに分ける。 コンパイラはドキュメントを読んで Validated IR を作る。 ランタイムはその IR を実行する。 二つは完全に分離している。 そのためプログラムは、ネットワークに触れる前に検査でき、保存でき、送信できる。

コンパイラは次の順序で段階を実行する。

  1. KDL の構文解析
  2. 基本制約の検証
  3. アプリケーション文法の検証
  4. import グラフの解決
  5. シンボル解決
  6. 型検査
  7. ケイパビリティの導出と検証

ある段階でエラーが出れば、そこから先の段階には進まない。 個々のエラーは、コードとソース位置を持つ診断になる。

適合実装は、ネットワークリクエストの送信、ブラウザの起動、ページの遷移、セッションの変更、外部トランスフォームの呼び出しのいずれよりも先に、段階 1 から 7 を完了しなければならない。 これは一実装の性質ではなく、言語の規則である。

コンパイラのパッケージは、ネットワーククライアントも、ブラウザ制御も、外部トランスフォームの呼び出しも持たない。 読むのはエントリの KDL ファイルと、そこから import される相対パスのモジュールだけである。 それ以上のことはしない。

TypeScript のコアは、ファイルシステムへの自動アクセスも、ネットワークローダも持たない。 相対パスを字句的に解決し、バイト列は SourceLoader に要求する。 ファイルシステム用のローダは @hsblabs/scrape-kdl/node エントリポイントが提供する。 したがってコアパッケージが、許可していないファイルを読むことはない。

パーサはプロパティの順序を保持し、重複もそのまま残す。 そのうえで意味解析の段階が、重複プロパティを E_DUPLICATE_PROPERTY として拒否する。 KDL 自体はこれを許すが、コンパイラが黙って最後のプロパティを採用することはない。

Validated IR は、プログラムが必要とするケイパビリティのソート済み集合を持つ。 コンパイラはこの集合をドキュメントの内容から算出する。

ケイパビリティ 発生条件
http.fetch HTTP ソース。
browser.navigate ブラウザソース。
browser.query ブラウザモードでの選択。
browser.read-textbrowser.read-htmlbrowser.read-attr ブラウザモードでの値ソース。
browser.waitbrowser.inputbrowser.scrollbrowser.network-idle ワークフローステップ。
browser.evaluate-js evaluate-js の値ソース。
transform.external:<symbol> 外部トランスフォーム。

この集合は契約である。 ホストはこれを読み、実行前にプログラムを拒否できる。 たとえば http.fetch だけを許可し、browser.* をすべて拒否するホストを書ける。 正確な一覧は language-v0.1.md にある。

IR は、コンパイラと各ランタイムのあいだの言語非依存な契約である。 Go ランタイムと TypeScript ランタイムは同じ IR を読み、同じ値を返す。

IR は、関係はあるが役割の異なる三つのバージョンフィールドを持つ。

  • irVersion:IR ドキュメントの形式。現在の値は 2026-07-15
  • languageVersion:ドキュメントが language-version で選んだ言語契約。現在の値は 2026-07-15
  • ドキュメントの version プロパティ:利用者側の版識別子。コンパイラはこれを解釈しないが、値は YYYY-MM-DD 形式の実在する暦日でなければならない。

IR のスキーマは schema.json にある。

一つの IR には三つの実行境界がある。

  • HTTP:ランタイムがリクエストを送り、ボディをデコードし、HTML を解析し、値を抽出する。HTTP 実行 を参照。
  • ブラウザ:利用者が渡したアダプタを通じて、実ページへ遷移し、ワークフローを実行し、値を読む。ブラウザモード を参照。
  • オフラインスナップショット:利用者が渡した HTML から抽出し、取得は行わない。オフラインスナップショット を参照。

JavaScript を使わない抽出では、HTTP ランタイムとブラウザランタイムの結果は一致しなければならない。 同一の適合フィクスチャが両方のランタイムを検証する。 両者の差異は許された揺れではなく、欠陥である。

コンパイラは静的診断を、import の解決順、ファイルパス、ソース内の位置、コードの順で整列する。 ランタイムは警告を実行順で整列する。

そのため、同じプログラムを同じ入力に対して 2 回実行すれば、同じ出力が得られる。 診断はテストや CI ジョブで比較できる。 詳細は 診断 を参照。