From c8f555a70a628031ec586c1ef4dc0b5055781d5c Mon Sep 17 00:00:00 2001 From: Seungpyo1007 Date: Sun, 1 Nov 2026 00:23:30 +0900 Subject: [PATCH] fix(site): count every collection in the growth chart build-history.mjs summed only the 8 collections the dump had in June, so the chart's latest point said 108,509 records while the API serves 213,487. It now counts all 13 manifest collections, including laptops, monitors, software, websites and the device catalog, and no longer prints git's "fatal:" for the commit that stopped tracking the manifest. The homepage also had no label for websites or device-catalog, so their history rows read "undefined". Both are labelled now, and any future collection falls back to its key. Refs #19 --- site/scripts/build-history.mjs | 16 ++++++++++++---- site/src/scripts/techapi.js | 16 +++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/site/scripts/build-history.mjs b/site/scripts/build-history.mjs index 381b6169f906..a5bca67aabaf 100644 --- a/site/scripts/build-history.mjs +++ b/site/scripts/build-history.mjs @@ -26,12 +26,17 @@ const TRACKED = "site/public/v1/index.json"; const OUT = resolve(SITE_DIR, "public/v1/history.json"); const REPO_URL = "https://github.com/GetTechAPI/TechAPI"; -// Categories we sum into the record total (matches the public dump manifest). -const ORDER = ["smartphones", "tablets", "watches", "pdas", "socs", "gpus", "cpus", "brands"]; +// Categories we sum into the record total: every collection in the public dump +// manifest (v1/index.json). Old manifests that predate a collection just lack it. +const ORDER = [ + "smartphones", "tablets", "laptops", "monitors", "watches", "pdas", "socs", "gpus", "cpus", + "brands", "software", "websites", "device-catalog", +]; // The data/ folder behind each of those collections. const DATA_DIR = { - smartphones: "smartphone", tablets: "tablet", watches: "watch", pdas: "pda", - socs: "soc", gpus: "gpu", cpus: "cpu", brands: "brand", + smartphones: "smartphone", tablets: "tablet", laptops: "laptop", monitors: "monitor", + watches: "watch", pdas: "pda", socs: "soc", gpus: "gpu", cpus: "cpu", brands: "brand", + software: "software", websites: "website", "device-catalog": "device_catalog", }; // Keep the chart legible if the history ever grows large: downsample to at most // MAX points, always preserving the first (baseline) and last (latest) commits. @@ -41,9 +46,12 @@ const MAX = 40; const DATA_MAX = 20; function git(args) { + // stderr is captured, not printed: a commit without the manifest (such as the + // one that stopped committing it) is skipped, not a "fatal:" line in the log. return execFileSync("git", ["-C", REPO_ROOT, ...args], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, + stdio: ["ignore", "pipe", "pipe"], }); } diff --git a/site/src/scripts/techapi.js b/site/src/scripts/techapi.js index 78502724482c..09239e4a22be 100644 --- a/site/src/scripts/techapi.js +++ b/site/src/scripts/techapi.js @@ -179,10 +179,12 @@ async function loadList(resource) { (function stats() { const el = document.getElementById("stats"); if (!el) return; - const order = ["games", "software", "smartphones", "laptops", "tablets", "monitors", "watches", "pdas", "socs", "gpus", "cpus", "brands"]; + const order = ["games", "software", "websites", "smartphones", "laptops", "tablets", "monitors", "watches", "pdas", "device-catalog", "socs", "gpus", "cpus", "brands"]; const label = { games: "games", software: "software", + websites: "websites", + "device-catalog": "device catalog", smartphones: "phones", laptops: "laptops", tablets: "tablets", @@ -244,10 +246,12 @@ function countUp(node, target, opts = {}) { const listEl = document.getElementById("history-list"); if (!totalEl || !countsEl || !chartEl || !listEl) return; - const order = ["games", "software", "smartphones", "laptops", "tablets", "monitors", "watches", "pdas", "socs", "gpus", "cpus", "brands"]; + const order = ["games", "software", "websites", "smartphones", "laptops", "tablets", "monitors", "watches", "pdas", "device-catalog", "socs", "gpus", "cpus", "brands"]; const label = { games: "Games", software: "Software", + websites: "Websites", + "device-catalog": "Device catalog", smartphones: "Phones", laptops: "Laptops", tablets: "Tablets", @@ -263,6 +267,8 @@ function countUp(node, target, opts = {}) { const shortLabel = { games: "games", software: "software", + websites: "websites", + "device-catalog": "device catalog", smartphones: "phones", laptops: "laptops", tablets: "tablets", @@ -295,7 +301,7 @@ function countUp(node, target, opts = {}) { const total = rows.reduce((sum, row) => sum + row.count, 0); totalEl.textContent = total.toLocaleString() + " records"; countsEl.innerHTML = rows.map((row) => - `
${label[row.key]}${row.count.toLocaleString()}
` + `
${label[row.key] || row.key}${row.count.toLocaleString()}
` ).join(""); } @@ -355,7 +361,7 @@ function countUp(node, target, opts = {}) { // max-height) so the full history stays reachable without a giant section. listEl.innerHTML = points.slice().reverse().map((point) => { const changes = point.changes.length - ? point.changes.map((row) => `${shortLabel[row.key]} ${formatDelta(row.delta)}`).join(", ") + ? point.changes.map((row) => `${shortLabel[row.key] || row.key} ${formatDelta(row.delta)}`).join(", ") : (point.baseline ? "baseline snapshot" : `total ${formatDelta(point.delta)}`); const tag = shortTitle(point.title); const delta = point.baseline ? "baseline" : formatDelta(point.delta); @@ -392,7 +398,7 @@ function countUp(node, target, opts = {}) { hDot.style.left = px + "px"; hDot.style.top = py + "px"; const chg = p.changes && p.changes.length - ? p.changes.map((row) => `${shortLabel[row.key]} ${formatDelta(row.delta)}`).join(", ") + ? p.changes.map((row) => `${shortLabel[row.key] || row.key} ${formatDelta(row.delta)}`).join(", ") : ""; hTip.innerHTML = `${esc(p.when)}` + `${p.total.toLocaleString()} records` +