From 53ba0515bff570c0ea1644551a47a039722ab863 Mon Sep 17 00:00:00 2001 From: Yashaswini K P Date: Thu, 18 Jun 2026 15:36:13 +0530 Subject: [PATCH 1/4] perf: ingest inactive users list and recycle cached leaderboard stats --- scripts/sync-leaderboard.js | 52 ++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/scripts/sync-leaderboard.js b/scripts/sync-leaderboard.js index 24470107..cd09715a 100644 --- a/scripts/sync-leaderboard.js +++ b/scripts/sync-leaderboard.js @@ -206,12 +206,62 @@ async function computeRankChanges(currentSorted, filename) { } const baseUrl = "https://leetcode-api-dun.vercel.app/"; + + const inactiveFilePath = path.join(DATA_DIR, "inactive-users.json"); + const inactiveUsersSet = new Set(); + try { + if (fs.existsSync(inactiveFilePath)) { + const rawInactive = fs.readFileSync(inactiveFilePath, "utf8"); + const inactiveData = JSON.parse(rawInactive); + if (Array.isArray(inactiveData.inactiveUsers)) { + inactiveData.inactiveUsers.forEach(id => inactiveUsersSet.add(id)); + console.log(`Loaded ${inactiveUsersSet.size} stale users into skip-filter lookup Set.`); + } + } + } catch (err) { + console.warn("Warning: Could not parse inactive-users.json, proceeding without skips:", err.message); + } + + const overallFilepath = path.join(DATA_DIR, "overall.json"); + let previousOverall = []; + try { + if (fs.existsSync(overallFilepath)) { + previousOverall = JSON.parse(fs.readFileSync(overallFilepath, "utf8")); + } + } catch (err) { + console.warn("No previous overall.json found, cannot recycle stale records."); + } + + const historyMap = new Map(); + previousOverall.forEach(oldUser => { + if (oldUser.id) historyMap.set(oldUser.id, oldUser); + }); + const interval = 0; let overallData = []; console.log(" "); console.log("Starting daily fetch..."); for (const user of users) { + if (inactiveUsersSet.has(user.id)) { + const cache = historyMap.get(user.id); + if (cache) { + console.log(`⏭️ ${user.name} (${user.id}): Bypassed API (Reusing cached stats)`); + overallData.push({ + name: cache.name, + id: cache.id, + data: { + easySolved: cache.data?.easySolved || 0, + mediumSolved: cache.data?.mediumSolved || 0, + hardSolved: cache.data?.hardSolved || 0, + totalSolved: cache.data?.totalSolved || 0 + }, + score: cache.score || 0 + }); + continue; + } + } + const data = await fetchData(baseUrl + user.id); if (!data) { console.log(`${user.name}: skipped (API error)`); @@ -269,7 +319,7 @@ async function computeRankChanges(currentSorted, filename) { console.log("Writing sorted daily data to overall file..."); const overallFilepath = path.join(DATA_DIR, "overall.json"); - let previousOverall = []; + previousOverall = []; try { const rawPrevious = fs.readFileSync(overallFilepath, "utf8"); previousOverall = JSON.parse(rawPrevious); From 35b25b99d2f64d2b8ca7f89ecd1dc8a40170eb05 Mon Sep 17 00:00:00 2001 From: Yashaswini K P Date: Fri, 19 Jun 2026 16:23:50 +0530 Subject: [PATCH 2/4] deleted log --- scripts/sync-leaderboard.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/sync-leaderboard.js b/scripts/sync-leaderboard.js index cd09715a..7dc2f924 100644 --- a/scripts/sync-leaderboard.js +++ b/scripts/sync-leaderboard.js @@ -246,7 +246,6 @@ async function computeRankChanges(currentSorted, filename) { if (inactiveUsersSet.has(user.id)) { const cache = historyMap.get(user.id); if (cache) { - console.log(`⏭️ ${user.name} (${user.id}): Bypassed API (Reusing cached stats)`); overallData.push({ name: cache.name, id: cache.id, From 99a8967491532f7df81d00a0511db40e1aea8036 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 19 Jun 2026 10:58:46 +0000 Subject: [PATCH 3/4] style: auto-format code with Prettier (/format) --- scripts/sync-leaderboard.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/scripts/sync-leaderboard.js b/scripts/sync-leaderboard.js index 7dc2f924..f7b719a1 100644 --- a/scripts/sync-leaderboard.js +++ b/scripts/sync-leaderboard.js @@ -214,12 +214,17 @@ async function computeRankChanges(currentSorted, filename) { const rawInactive = fs.readFileSync(inactiveFilePath, "utf8"); const inactiveData = JSON.parse(rawInactive); if (Array.isArray(inactiveData.inactiveUsers)) { - inactiveData.inactiveUsers.forEach(id => inactiveUsersSet.add(id)); - console.log(`Loaded ${inactiveUsersSet.size} stale users into skip-filter lookup Set.`); + inactiveData.inactiveUsers.forEach((id) => inactiveUsersSet.add(id)); + console.log( + `Loaded ${inactiveUsersSet.size} stale users into skip-filter lookup Set.`, + ); } } } catch (err) { - console.warn("Warning: Could not parse inactive-users.json, proceeding without skips:", err.message); + console.warn( + "Warning: Could not parse inactive-users.json, proceeding without skips:", + err.message, + ); } const overallFilepath = path.join(DATA_DIR, "overall.json"); @@ -229,11 +234,13 @@ async function computeRankChanges(currentSorted, filename) { previousOverall = JSON.parse(fs.readFileSync(overallFilepath, "utf8")); } } catch (err) { - console.warn("No previous overall.json found, cannot recycle stale records."); + console.warn( + "No previous overall.json found, cannot recycle stale records.", + ); } const historyMap = new Map(); - previousOverall.forEach(oldUser => { + previousOverall.forEach((oldUser) => { if (oldUser.id) historyMap.set(oldUser.id, oldUser); }); @@ -253,9 +260,9 @@ async function computeRankChanges(currentSorted, filename) { easySolved: cache.data?.easySolved || 0, mediumSolved: cache.data?.mediumSolved || 0, hardSolved: cache.data?.hardSolved || 0, - totalSolved: cache.data?.totalSolved || 0 + totalSolved: cache.data?.totalSolved || 0, }, - score: cache.score || 0 + score: cache.score || 0, }); continue; } From 26a4b2f73c72805e8e6a9cdb781f75702944f9e3 Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sat, 20 Jun 2026 18:41:54 +0530 Subject: [PATCH 4/4] Simplify inactive users handling in sync-leaderboard --- scripts/sync-leaderboard.js | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/scripts/sync-leaderboard.js b/scripts/sync-leaderboard.js index f7b719a1..6081fb8a 100644 --- a/scripts/sync-leaderboard.js +++ b/scripts/sync-leaderboard.js @@ -213,12 +213,10 @@ async function computeRankChanges(currentSorted, filename) { if (fs.existsSync(inactiveFilePath)) { const rawInactive = fs.readFileSync(inactiveFilePath, "utf8"); const inactiveData = JSON.parse(rawInactive); - if (Array.isArray(inactiveData.inactiveUsers)) { - inactiveData.inactiveUsers.forEach((id) => inactiveUsersSet.add(id)); - console.log( - `Loaded ${inactiveUsersSet.size} stale users into skip-filter lookup Set.`, - ); - } + inactiveData.inactiveUsers.forEach((id) => inactiveUsersSet.add(id)); + console.log( + `Loaded ${inactiveUsersSet.size} stale users into skip-filter lookup Set.`, + ); } } catch (err) { console.warn( @@ -241,7 +239,7 @@ async function computeRankChanges(currentSorted, filename) { const historyMap = new Map(); previousOverall.forEach((oldUser) => { - if (oldUser.id) historyMap.set(oldUser.id, oldUser); + historyMap.set(oldUser.id, oldUser); }); const interval = 0; @@ -253,17 +251,8 @@ async function computeRankChanges(currentSorted, filename) { if (inactiveUsersSet.has(user.id)) { const cache = historyMap.get(user.id); if (cache) { - overallData.push({ - name: cache.name, - id: cache.id, - data: { - easySolved: cache.data?.easySolved || 0, - mediumSolved: cache.data?.mediumSolved || 0, - hardSolved: cache.data?.hardSolved || 0, - totalSolved: cache.data?.totalSolved || 0, - }, - score: cache.score || 0, - }); + console.log(`${user.name}: recycled (inactive)`); + overallData.push(cache); continue; } } @@ -323,15 +312,6 @@ async function computeRankChanges(currentSorted, filename) { stableSortByScore(overallData); assignCompetitionRanks(overallData); console.log("Writing sorted daily data to overall file..."); - const overallFilepath = path.join(DATA_DIR, "overall.json"); - - previousOverall = []; - try { - const rawPrevious = fs.readFileSync(overallFilepath, "utf8"); - previousOverall = JSON.parse(rawPrevious); - } catch (err) { - console.warn("No previous overall.json found, skipping diff."); - } await computeRankChanges(overallData, "overall.json"); try {