v7.4.0
v7.4.0
Reduced how often the app asks GitHub at startup, so that community content keeps loading even where many people share one connection, such as a classroom. Until now every page load spent four GitHub API requests (listing official races, community courses, community programs and community car types). Unauthenticated, that API allows only 60 requests per hour per connection (IP address), and we measured that the ceiling is reached after 15 page loads. In a classroom where ten people open the page over the same venue Wi-Fi, a few loads each was enough to exhaust it, and community courses and programs would report "could not be retrieved" (the simulator itself never stops, so driving still worked). Three changes address this. (1) Listings are now read from an index.json inside each directory. That host (raw.githubusercontent.com) has no request-count limit; we confirmed by measurement that its responses carry no rate-limit headers. Once the upstream repository ships an index.json, listing community courses, programs and car types uses no API requests at all. Only the official race listing still uses the API, because it has to enumerate directories, which an index.json cannot stand in for; that one is covered by (3) below. (2) Repositories without an index.json (older clones and forks) keep using the API exactly as before, so nothing changes for them. (3) Retrieved listings are held in the browser for a while, and no request is made during that time. The hold time depends on where the listing came from: five minutes for the unlimited manifest, one hour for the scarce API and for "not created yet" (404) results. The races/ directory in particular does not exist yet, so until now every single load spent one request that was guaranteed to miss; that miss is now remembered too. Race entry listings go through the same path as well, because previously each event cost one API request, which meant four concurrent events would put startup back at four requests. We also tried conditional requests with ETag, but measured that even a 304 Not Modified consumes one request (remaining 57 to 56 to 55), so we did not adopt it. The reload buttons in both the Official Races and the Rankings dialogs discard the held listing before fetching, so pressing either always gives you the latest. Expect new submissions to take up to about ten minutes to appear: the five-minute browser hold sits on top of roughly five minutes of caching on the delivery side. On safety, filenames written in index.json are no longer trusted as-is: path separators and relative references (../) are rejected, and names containing symbols or non-ASCII characters are URL-encoded before being fetched (joined raw, "a#b.json" would point at a different file). Everything happens inside the browser; no server-side machinery was added, keeping this repository self-contained. Driving physics, the f0-f3 determinism hashes, the verifyHash of official records and share URLs are all unchanged.
日本語
起動時に GitHub へ問い合わせる回数を減らし、教室のように1つの回線を大勢で共有する場所でも「みんなの投稿」が読めなくなりにくくしました。従来はページを開くたびに GitHub の API を4回(公式レース・投稿コース・投稿プログラム・投稿車種の一覧)使っていました。この API は認証なしだと回線(IPアドレス)あたり毎時60回までで、実測すると15回開いた時点で上限に達します。10人が同じ会場Wi-Fiから開く教室では、数回ずつ開いただけで打ち止めになり、投稿コースや投稿プログラムが「取得できませんでした」になっていました(本体は止まらない設計なので走行はできます)。対策を3つ入れています。①一覧をディレクトリ内の index.json から読むようにしました。この読み取り先(raw.githubusercontent.com)には API の回数制限がありません(応答に制限ヘッダが存在しないことを実測で確認しました)。上流リポジトリに index.json が置かれれば、投稿コース・投稿プログラム・投稿車種の一覧は API を1回も使わなくなります。公式レースの一覧だけはディレクトリを数える必要があり、index.json では代用できないため API のままです(こちらは下の③で覚えます)。②index.json が無いリポジトリ(古いクローンやフォーク)では従来どおり API を使うので、動作は変わりません。③取得した一覧をブラウザに一時保存し、その間は問い合わせません。保存時間は取得元で変えていて、制限のないマニフェスト由来は5分、貴重な API 由来と「まだ作られていない」(404)は1時間です。とくに公式レースのraces/ はまだ存在しないため、これまで毎回100%空振りの問い合わせを1回していましたが、これも覚えるようにしました。あわせて、大会のエントリー一覧も同じ仕組みを通しました(従来は大会1件につきAPI を1回使っており、大会を4本開催すると起動あたり4回で元の水準に戻ってしまうためです)。なお ETag による条件付き取得も試しましたが、304(変更なし)でも1回消費することを実測で確認したため採用していません(残り57→56→55)。「公式レース」と「ランキング」の再読込ボタンはどちらも一時保存を捨ててから取り直すので、押せば必ず最新になります。新しい投稿が見えるまでの遅れは、index.json 由来の5分に配信側(raw)のキャッシュ約5分が乗るため、最大で10分ほどとお考えください。安全面では、index.json に書かれたファイル名を素通しせず、ディレクトリ区切りや相対参照(../)を弾き、記号や日本語を含む名前をURL エンコードしてから取りに行くようにしています(素のまま繋ぐと「a#b.json」が別のファイルを指します)。すべてブラウザ内で完結する変更で、サーバ側の仕組みは増やしていません(このリポジトリは単体で完結するという方針のままです)。走行物理・決定論ハッシュf0〜f3・公式記録の verifyHash・共有URLはすべて不変です。
Verifying this release yourself
cd Simulator
node wf_run_all.mjs # the full assertion-gate suiteThe suite runs from a fresh clone with no dependencies beyond Node.js.
The real-browser checks under Simulator/browser/ additionally need npm install and a display.