mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-11-09 10:39:41 -06:00
"28,106 stars on GitHub" is injected by inject_stats.py from site/config/stats-cache.json at render time, so it is right when the site is built and never again. The main site handles this: site/index.qmd re-fetches on every page load, both from stats.json (refreshed to gh-pages every six hours) and directly from the GitHub API, with the comment that the star count "should track the repo to the second rather than to the last scheduled refresh". This site got the first half only. It emits the same data-stat="stars" hook on two elements of the landing page but shipped nothing to hydrate them, and it never reads stats.json at all, so a CDN-cached page served the build-time number indefinitely. The committed cache was generated 2026-09-14 and read 28,106; the API returned 28,258 today, 152 behind after three days. The star count is public, so this fetches it directly rather than waiting on a refresh cycle this site does not consume. On rate limit, offline or a blocked request the rendered value stays, so the page always shows a real number. Verified in a browser: both elements read 28,106 at first paint and 28,258 after hydration.
32 lines
1.5 KiB
JavaScript
32 lines
1.5 KiB
JavaScript
<script>
|
|
// Keep the GitHub star count current after deploy.
|
|
//
|
|
// inject_stats.py substitutes {{stats.stars}} at render time, so the number is
|
|
// correct at the moment the site is built and then frozen. The main site solves
|
|
// this in site/index.qmd by re-fetching on every page load; this site emitted
|
|
// the same data-stat="stars" hook but shipped nothing to hydrate it, so a
|
|
// CDN-cached page showed whatever the cache held at the last publish. The
|
|
// cached value was 152 stars behind within three days.
|
|
//
|
|
// The star count is public and needs no credential, so it is fetched directly
|
|
// from the API rather than waiting on the six-hourly stats.json refresh, which
|
|
// this site does not consume. On any failure the build-time value simply
|
|
// stays, which is why the elements are never emptied first.
|
|
(function () {
|
|
var nodes = document.querySelectorAll('[data-stat="stars"]');
|
|
if (!nodes.length) return;
|
|
|
|
fetch('https://api.github.com/repos/harvard-edge/cs249r_book')
|
|
.then(function (r) { return r.ok ? r.json() : Promise.reject(r.status); })
|
|
.then(function (d) {
|
|
if (!d || typeof d.stargazers_count !== 'number') return;
|
|
var formatted = d.stargazers_count.toLocaleString('en-US');
|
|
nodes.forEach(function (n) { n.textContent = formatted; });
|
|
})
|
|
.catch(function (err) {
|
|
// Rate limit, offline, blocked: the rendered value is still a real number.
|
|
console.warn('[tinytorch] star count refresh failed, showing build-time value:', err);
|
|
});
|
|
})();
|
|
</script>
|