import { getLeagueData } from './leagueData'; import { leagueID } from '$lib/utils/leagueInfo'; import { getNflState } from './nflState'; import { getLeagueRosters } from "./leagueRosters" import { getLeagueUsers } from "./leagueUsers" import { waitForAll } from './multiPromise'; import { get } from 'svelte/store'; import {records} from '$lib/stores'; export const getLeagueRecords = async (refresh = false) => { if(get(records).seasonWeekRecords) { return get(records); } // if this isn't a refresh data call, check if there are already transactions stored in localStorage if(!refresh) { let localRecords = await JSON.parse(localStorage.getItem("records")); // check if transactions have been saved to localStorage before if(localRecords) { localRecords.stale = true; return localRecords; } } const nflState = await getNflState().catch((err) => { console.error(err); }); let week = 0; if(nflState.season_type == 'regular') { week = nflState.week - 1; } else if(nflState.season_type == 'post') { week = 18; } let curSeason = leagueID; let currentManagers; let currentYear; let lastYear; let allTimeMatchupDifferentials = []; let leagueRosterRecords = {}; // every full season stat point (for each year and all years combined) let seasonWeekRecords = []; // highest weekly points within a single season let leagueWeekRecords = []; // highest weekly points within a single season let mostSeasonLongPoints = []; // 10 highest full season points let allTimeBiggestBlowouts = []; // 10 biggest blowouts let allTimeClosestMatchups = []; // 10 closest matchups let allTimePOMatchupDifferentials = []; let playoffRosterRecords = {}; let playoffWeekRecords = []; let leaguePOWeekRecords = []; let mostPlayoffLongPoints = []; while(curSeason && curSeason != 0) { const [rosterRes, users, leagueData] = await waitForAll( getLeagueRosters(curSeason), getLeagueUsers(curSeason), getLeagueData(curSeason), ).catch((err) => { console.error(err); }); let year = parseInt(leagueData.season); // variables for playoff records let numPOTeams = parseInt(leagueData.settings.playoff_teams); let playoffStart = parseInt(leagueData.settings.playoff_week_start); let playoffLength; let playoffType; let playoffCase; // for determining relevant (ie. PO bracket) matches // before 2020, 1 week/round was only option; in 2020, 2 weeks/rounds added; in 2021, 1 week/round + 2 champ if(year > 2019) { playoffType = parseInt(leagueData.settings.playoff_round_type); } else { playoffType = 0; } // set length of playoffs if(playoffType == 0) { if(numPOTeams == 6) { playoffLength = 3; playoffCase = 1; } else if(numPOTeams == 8) { playoffLength = 3; playoffCase = 2; } else if(numPOTeams == 4) { playoffLength = 2; playoffCase = 3; } } else if(playoffType == 1 && year > 2020) { if(numPOTeams == 6) { playoffLength = 4; playoffCase = 4; } else if(numPOTeams == 8) { playoffLength = 4; playoffCase = 5 } else if(numPOTeams == 4) { playoffLength = 3; playoffCase = 6; } } else if(playoffType == 2 || playoffType == 1 && year == 2020) { if(numPOTeams == 6) { playoffLength = 6; playoffCase = 7; } else if (numPOTeams == 8) { playoffLength = 6; playoffCase = 8; } else if (numPOTeams == 4) { playoffLength = 4; playoffCase = 9; } } POrecordsWeek = playoffStart + playoffLength - 1; // on first run, week is provided above from nflState, // after that get the final week of regular season from leagueData if(leagueData.status == 'complete' || week > leagueData.settings.playoff_week_start - 1) { week = leagueData.settings.playoff_week_start - 1; } lastYear = year; const rosters = rosterRes.rosters; const originalManagers = {}; for(const roster of rosters) { const rosterID = roster.roster_id; const user = users[roster.owner_id]; if(user) { originalManagers[rosterID] = { avatar: `https://sleepercdn.com/avatars/thumbs/${user.avatar}`, name: user.metadata.team_name ? user.metadata.team_name : user.display_name, } } else { originalManagers[rosterID] = { avatar: `https://sleepercdn.com/images/v2/icons/player_default.webp`, name: 'Unknown Manager', } } if(roster.settings.wins == 0 && roster.settings.ties == 0 && roster.settings.losses == 0) continue; if(!leagueRosterRecords[rosterID]) { leagueRosterRecords[rosterID] = { wins: 0, losses: 0, ties: 0, fptsFor: 0, fptsAgainst: 0, potentialPoints: 0, years: [] } } const fpts = roster.settings.fpts + (roster.settings.fpts_decimal / 100); const fptsAgainst = roster.settings.fpts_against + (roster.settings.fpts_against_decimal / 100); const potentialPoints = roster.settings.ppts + (roster.settings.ppts_decimal / 100); // add records to league roster record record leagueRosterRecords[rosterID].wins += roster.settings.wins; leagueRosterRecords[rosterID].losses += roster.settings.losses; leagueRosterRecords[rosterID].ties += roster.settings.ties; leagueRosterRecords[rosterID].fptsFor += fpts; leagueRosterRecords[rosterID].fptsAgainst += fptsAgainst; leagueRosterRecords[rosterID].potentialPoints += potentialPoints; // add singleSeason info [`${year}fptsFor`] const singleYearInfo = { wins: roster.settings.wins, losses: roster.settings.losses, ties: roster.settings.ties, fpts, fptsAgainst, potentialPoints, manager: originalManagers[rosterID], year } leagueRosterRecords[rosterID].years.push(singleYearInfo); mostSeasonLongPoints.push({ rosterID, fpts, year, manager: originalManagers[rosterID] }) if(!playoffRosterRecords[recordManID]) { playoffRosterRecords[recordManID] = { wins: 0, losses: 0, ties: 0, fptsFor: 0, fptsAgainst: 0, potentialPoints: 0, fptspg: 0, POgames: 0, manager: originalManagers[recordManID], years: {}, recordManID, } } playoffRosterRecords[recordManID].years[year] = { wins: 0, losses: 0, ties: 0, fpts: 0, fptsAgainst: 0, potentialPoints: 0, fptspg: 0, POgames: 0, manager: originalManagers[recordManID], year, recordManID, } } if(!currentManagers) { currentManagers = originalManagers; } // loop through each week of the season const matchupsPromises = []; let startWeek = parseInt(week); const POmatchupsPromises = []; let POstartWeek = parseInt(POrecordsWeek); while(week > 0) { matchupsPromises.push(fetch(`https://api.sleeper.app/v1/league/${curSeason}/matchups/${week}`, {compress: true})) week--; } while(POrecordsWeek > playoffStart - 1) { POmatchupsPromises.push(fetch(`https://api.sleeper.app/v1/league/${curSeason}/matchups/${POrecordsWeek}`, {compress: true})) POrecordsWeek--; } const matchupsRes = await waitForAll(...matchupsPromises).catch((err) => { console.error(err); }); const POmatchupsRes = await waitForAll(...POmatchupsPromises).catch((err) => { console.error(err); }); // convert the json matchup responses const matchupsJsonPromises = []; for(const matchupRes of matchupsRes) { const data = matchupRes.json(); matchupsJsonPromises.push(data) if (!matchupRes.ok) { throw new Error(data); } } const matchupsData = await waitForAll(...matchupsJsonPromises).catch((err) => { console.error(err); }); const POmatchupsJsonPromises = []; for(const POmatchupRes of POmatchupsRes) { const POdata = POmatchupRes.json(); POmatchupsJsonPromises.push(POdata) if (!POmatchupRes.ok) { throw new Error(POdata); } } const POmatchupsData = await waitForAll(...POmatchupsJsonPromises).catch((err) => { console.error(err); }); // now that we've used the current season ID for everything we need, set it to the previous season curSeason = leagueData.previous_league_id; const seasonPointsRecord = []; let matchupDifferentials = []; const playoffPointsRecord = []; let POmatchupDifferentials = []; if(startWeek > playoffStart - 1 || leagueData.status == 'complete') { // process all the PLAYOFFS matchups for(const POmatchupWeek of POmatchupsData) { let POmatchups = {}; let POround = POstartWeek - POrecordsWeek; const POentry = { manager: originalManagers[recordManID], fpts: POmatchup.points, week: POstartWeek, year, rosterID: POmatchup.roster_id, recordManID, } // add each entry to the POmatchup object if(!POmatchups[POmatchup.matchup_id]) { POmatchups[POmatchup.matchup_id] = []; } POmatchups[POmatchup.matchup_id].push(POentry); } if(playoffCase == 4 && POstartWeek == POrecordsWeek + playoffLength || // Relevant Match IDs: 1 playoffCase == 5 && POstartWeek == POrecordsWeek + playoffLength || playoffCase == 6 && POstartWeek == POrecordsWeek + playoffLength) { const champMatch = POmatchups[1]; let home = champMatch[0]; let away = champMatch[1]; if(champMatch[0].fpts < champMatch[1].fpts) { home = champMatch[1]; away = champMatch[0]; } const POmatchupDifferential = { year: home.year, week: home.week, home: { manager: home.manager, fpts: home.fpts, recordManID: home.recordManID, }, away: { manager: away.manager, fpts: away.fpts, recordManID: away.recordManID, }, differential: home.fpts - away.fpts } allTimePOMatchupDifferentials.push(POmatchupDifferential); POmatchupDifferentials.push(POmatchupDifferential); for(const key in champMatch) { const opponent = champMatch[key]; playoffRosterRecords[opponent.recordManID].years[year].fpts += opponent.fpts; playoffRosterRecords[opponent.recordManID].years[year].POgames++; const POweekEntry = { manager: opponent.manager, recordManID: opponent.recordManID, rosterID: opponent.rosterID, fpts: opponent.fpts, week: opponent.week, year, } playoffPointsRecord.push(POweekEntry); leaguePOWeekRecords.push(POweekEntry); } playoffRosterRecords[home.recordManID].years[year].fptsAgainst += away.fpts; playoffRosterRecords[away.recordManID].years[year].fptsAgainst += home.fpts; if(POmatchupDifferential.differential == 0) { playoffRosterRecords[home.recordManID].years[year].ties++; playoffRosterRecords[away.recordManID].years[year].ties++; } else { playoffRosterRecords[home.recordManID].years[year].wins++; playoffRosterRecords[away.recordManID].years[year].losses++; } } else if(playoffCase == 3 || // Relevant Match IDs: 1, 2 playoffCase == 9 || playoffCase == 6 && POstartWeek < POrecordsWeek + playoffLength || playoffCase == 1 && POround != 2 || playoffCase == 4 && POround == 1 || playoffCase == 4 && POround == 3 || playoffCase == 7 && POround < 3 || playoffCase == 7 && POround > 4) { for(let i = 1; i < 3; i++) { let home = POmatchups[i][0]; let away = POmatchups[i][1]; if(POmatchups[i][0].fpts < POmatchups[i][1].fpts) { home = POmatchups[i][1]; away = POmatchups[i][0]; } const POmatchupDifferential = { year: home.year, week: home.week, home: { manager: home.manager, fpts: home.fpts, recordManID: home.recordManID, }, away: { manager: away.manager, fpts: away.fpts, recordManID: away.recordManID, }, differential: home.fpts - away.fpts } allTimePOMatchupDifferentials.push(POmatchupDifferential); POmatchupDifferentials.push(POmatchupDifferential); for(const key in POmatchups[i]) { const opponent = POmatchups[i][key]; playoffRosterRecords[opponent.recordManID].years[year].fpts += opponent.fpts; playoffRosterRecords[opponent.recordManID].years[year].POgames++; const POweekEntry = { manager: opponent.manager, recordManID: opponent.recordManID, rosterID: opponent.rosterID, fpts: opponent.fpts, week: opponent.week, year, } playoffPointsRecord.push(POweekEntry); leaguePOWeekRecords.push(POweekEntry); } playoffRosterRecords[home.recordManID].years[year].fptsAgainst += away.fpts; playoffRosterRecords[away.recordManID].years[year].fptsAgainst += home.fpts; if(POmatchupDifferential.differential == 0) { playoffRosterRecords[home.recordManID].years[year].ties++; playoffRosterRecords[away.recordManID].years[year].ties++; } else { playoffRosterRecords[home.recordManID].years[year].wins++; playoffRosterRecords[away.recordManID].years[year].losses++; } } } else if(playoffCase == 7 && 2 < POround < 5 || // Relevant Match IDs: 1, 2, 3 playoffCase == 4 && POround == 2 || playoffCase == 1 && POround == 2) { for(let i = 1; i < 4; i++) { let home = POmatchups[i][0]; let away = POmatchups[i][1]; if(POmatchups[i][0].fpts < POmatchups[i][1].fpts) { home = POmatchups[i][1]; away = POmatchups[i][0]; } const POmatchupDifferential = { year: home.year, week: home.week, home: { manager: home.manager, fpts: home.fpts, recordManID: home.recordManID, }, away: { manager: away.manager, fpts: away.fpts, recordManID: away.recordManID, }, differential: home.fpts - away.fpts } allTimePOMatchupDifferentials.push(POmatchupDifferential); POmatchupDifferentials.push(POmatchupDifferential); for(const key in POmatchups[i]) { const opponent = POmatchups[i][key]; playoffRosterRecords[opponent.recordManID].years[year].fpts += opponent.fpts; playoffRosterRecords[opponent.recordManID].years[year].POgames++; const POweekEntry = { manager: opponent.manager, recordManID: opponent.recordManID, rosterID: opponent.rosterID, fpts: opponent.fpts, week: opponent.week, year, } playoffPointsRecord.push(POweekEntry); leaguePOWeekRecords.push(POweekEntry); } playoffRosterRecords[home.recordManID].years[year].fptsAgainst += away.fpts; playoffRosterRecords[away.recordManID].years[year].fptsAgainst += home.fpts; if(POmatchupDifferential.differential == 0) { playoffRosterRecords[home.recordManID].years[year].ties++; playoffRosterRecords[away.recordManID].years[year].ties++; } else { playoffRosterRecords[home.recordManID].years[year].wins++; playoffRosterRecords[away.recordManID].years[year].losses++; } } } else if(playoffCase == 8 || // Relevant Match IDs: 1, 2, 3, 4 playoffCase == 2 || playoffCase == 5 && POstartWeek < POrecordsWeek + playoffLength) { for(let i = 1; i < 5; i++) { let home = POmatchups[i][0]; let away = POmatchups[i][1]; if(POmatchups[i][0].fpts < POmatchups[i][1].fpts) { home = POmatchups[i][1]; away = POmatchups[i][0]; } const POmatchupDifferential = { year: home.year, week: home.week, home: { manager: home.manager, fpts: home.fpts, recordManID: home.recordManID, }, away: { manager: away.manager, fpts: away.fpts, recordManID: away.recordManID, }, differential: home.fpts - away.fpts } allTimePOMatchupDifferentials.push(POmatchupDifferential); POmatchupDifferentials.push(POmatchupDifferential); for(const key in POmatchups[i]) { const opponent = POmatchups[i][key]; playoffRosterRecords[opponent.recordManID].years[year].fpts += opponent.fpts; playoffRosterRecords[opponent.recordManID].years[year].POgames++; const POweekEntry = { manager: opponent.manager, recordManID: opponent.recordManID, rosterID: opponent.rosterID, fpts: opponent.fpts, week: opponent.week, year, } playoffPointsRecord.push(POweekEntry); leaguePOWeekRecords.push(POweekEntry); } playoffRosterRecords[home.recordManID].years[year].fptsAgainst += away.fpts; playoffRosterRecords[away.recordManID].years[year].fptsAgainst += home.fpts; if(POmatchupDifferential.differential == 0) { playoffRosterRecords[home.recordManID].years[year].ties++; playoffRosterRecords[away.recordManID].years[year].ties++; } else { playoffRosterRecords[home.recordManID].years[year].wins++; playoffRosterRecords[away.recordManID].years[year].losses++; } } } POstartWeek--; } for(const recordManID in playoffRosterRecords) { const playoffRosterRecord = playoffRosterRecords[recordManID]; if(playoffRosterRecord.years[year] && playoffRosterRecord.years[year].POgames > 0) { playoffRosterRecord.fptsFor += playoffRosterRecord.years[year].fpts; playoffRosterRecord.fptsAgainst += playoffRosterRecord.years[year].fptsAgainst; playoffRosterRecord.wins += playoffRosterRecord.years[year].wins; playoffRosterRecord.ties += playoffRosterRecord.years[year].ties; playoffRosterRecord.losses += playoffRosterRecord.years[year].losses; playoffRosterRecord.POgames += playoffRosterRecord.years[year].POgames; playoffRosterRecord.potentialPoints += playoffRosterRecord.years[year].potentialPoints; const fptspg = playoffRosterRecord.years[year].fpts / playoffRosterRecord.years[year].POgames; const POlongEntry = { recordManID, fpts: playoffRosterRecord.years[year].fpts, fptspg, manager: playoffRosterRecord.years[year].manager, year, } mostPlayoffLongPoints.push(POlongEntry); } else { continue; } } POmatchupDifferentials = POmatchupDifferentials.sort((a, b) => b.differential - a.differential); const biggestPOBlowouts = POmatchupDifferentials.slice(0, 10); const closestPOMatchups = []; for(let i = 0; i < 10; i++) { closestPOMatchups.push(POmatchupDifferentials.pop()); } // per-season ranks & records to push thru seasonWeekRecords const interSeasonPOEntry = { year, biggestPOBlowouts, closestPOMatchups, playoffPointsRecords: playoffPointsRecord.sort((a, b) => b.fpts - a.fpts).slice(0, 10), } if(interSeasonPOEntry.playoffPointsRecords.length > 0) { if(!currentYear) { currentYear = year; } playoffWeekRecords.push(interSeasonPOEntry); }; } // process all the matchups for(const matchupWeek of matchupsData) { let matchups = {}; for(const matchup of matchupWeek) { const entry = { manager: originalManagers[matchup.roster_id], fpts: matchup.points, week: startWeek, year, rosterID: matchup.roster_id } seasonPointsRecord.push(entry); leagueWeekRecords.push(entry); // add each entry to the matchup object if(!matchups[matchup.matchup_id]) { matchups[matchup.matchup_id] = []; } matchups[matchup.matchup_id].push(entry); } startWeek--; // create matchup differentials from matchups obj for(const matchupKey in matchups) { const matchup = matchups[matchupKey]; let home = matchup[0]; let away = matchup[1]; if(matchup[0].fpts < matchup[1].fpts) { home = matchup[1]; away = matchup[0]; } const matchupDifferential = { year: home.year, week: home.week, home: { manager: home.manager, fpts: home.fpts, rosterID: home.rosterID, }, away: { manager: away.manager, fpts: away.fpts, rosterID: away.rosterID, }, differential: home.fpts - away.fpts } allTimeMatchupDifferentials.push(matchupDifferential); matchupDifferentials.push(matchupDifferential); } } matchupDifferentials = matchupDifferentials.sort((a, b) => b.differential - a.differential); const biggestBlowouts = matchupDifferentials.slice(0, 10); const closestMatchups = []; for(let i = 0; i < 10; i++) { closestMatchups.push(matchupDifferentials.pop()); } const interSeasonEntry = { year, biggestBlowouts, closestMatchups, seasonPointsRecords: seasonPointsRecord.sort((a, b) => b.fpts - a.fpts).slice(0, 10) } if(interSeasonEntry.seasonPointsRecords.length > 0) { if(!currentYear) { currentYear = year; } seasonWeekRecords.push(interSeasonEntry) }; } allTimeMatchupDifferentials = allTimeMatchupDifferentials.sort((a, b) => b.differential - a.differential) allTimeBiggestBlowouts = allTimeMatchupDifferentials.slice(0, 10); for(let i = 0; i < 10; i++) { allTimeClosestMatchups.push(allTimeMatchupDifferentials.pop()); } leagueWeekRecords = leagueWeekRecords.sort((a, b) => b.fpts - a.fpts).slice(0, 10); mostSeasonLongPoints = mostSeasonLongPoints.sort((a, b) => b.fpts - a.fpts).slice(0, 10); // Sorting - PLAYOFFS allTimePOMatchupDifferentials = allTimePOMatchupDifferentials.sort((a, b) => b.differential - a.differential); allTimeBiggestPOBlowouts = allTimePOMatchupDifferentials.slice(0, 10); for(let i = 0; i < 10; i++) { allTimeClosestPOMatchups.push(allTimePOMatchupDifferentials.pop()); } leaguePOWeekRecords = leaguePOWeekRecords.sort((a, b) => b.fpts - a.fpts).slice(0, 10); mostPlayoffLongPoints = mostPlayoffLongPoints.sort((a, b) => b.fptspg - a.fptspg).slice(0, 10); // sorting by ppg makes more sense (more accurately reflects top playoff-long performances) due to bye weeks const recordsData = { allTimeBiggestBlowouts, allTimeClosestMatchups, mostSeasonLongPoints, leagueWeekRecords, seasonWeekRecords, leagueRosterRecords, playoffWeekRecords, playoffRosterRecords, leaguePOWeekRecords, allTimeBiggestPOBlowouts, allTimeClosestPOMatchups, mostPlayoffLongPoints, currentManagers, currentYear, lastYear }; // update localStorage localStorage.setItem("records", JSON.stringify(recordsData)); records.update(() => recordsData); return recordsData; }