Codex commited on
Commit ·
e4fef26
1
Parent(s): 3c3ae66
Speed up baseball profile chart lookups
Browse files- src/matchups.js +84 -16
src/matchups.js
CHANGED
|
@@ -2127,14 +2127,7 @@ export class MatchupService {
|
|
| 2127 |
|
| 2128 |
async getHrProfileData(options = {}) {
|
| 2129 |
return this.getCachedChartValue(this.buildChartCacheKey('hr-profile', options), async () => {
|
| 2130 |
-
const result = await this.
|
| 2131 |
-
...options,
|
| 2132 |
-
player: options.player,
|
| 2133 |
-
playerType: 'hitter',
|
| 2134 |
-
});
|
| 2135 |
-
if (result.playerType !== 'hitter') {
|
| 2136 |
-
throw new Error(`No hitter matchup profile matched "${options.player}".`);
|
| 2137 |
-
}
|
| 2138 |
const overview = result.overview ?? {};
|
| 2139 |
return {
|
| 2140 |
...result,
|
|
@@ -2162,14 +2155,7 @@ export class MatchupService {
|
|
| 2162 |
|
| 2163 |
async getKProfileData(options = {}) {
|
| 2164 |
return this.getCachedChartValue(this.buildChartCacheKey('k-profile', options), async () => {
|
| 2165 |
-
const result = await this.
|
| 2166 |
-
...options,
|
| 2167 |
-
player: options.pitcher,
|
| 2168 |
-
playerType: 'pitcher',
|
| 2169 |
-
});
|
| 2170 |
-
if (result.playerType !== 'pitcher') {
|
| 2171 |
-
throw new Error(`No pitcher matchup profile matched "${options.pitcher}".`);
|
| 2172 |
-
}
|
| 2173 |
const overview = result.overview ?? {};
|
| 2174 |
return {
|
| 2175 |
...result,
|
|
@@ -2560,6 +2546,88 @@ export class MatchupService {
|
|
| 2560 |
return points.reverse();
|
| 2561 |
}
|
| 2562 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2563 |
async enrichHostedHitters(result, options = {}, methodName = 'getTopHitters') {
|
| 2564 |
if (!result?.rows?.length || !this.fallback?.getHitterSnapshotRows) {
|
| 2565 |
return result;
|
|
|
|
| 2127 |
|
| 2128 |
async getHrProfileData(options = {}) {
|
| 2129 |
return this.getCachedChartValue(this.buildChartCacheKey('hr-profile', options), async () => {
|
| 2130 |
+
const result = await this.getFastHitterChartContext(options.player, options);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2131 |
const overview = result.overview ?? {};
|
| 2132 |
return {
|
| 2133 |
...result,
|
|
|
|
| 2155 |
|
| 2156 |
async getKProfileData(options = {}) {
|
| 2157 |
return this.getCachedChartValue(this.buildChartCacheKey('k-profile', options), async () => {
|
| 2158 |
+
const result = await this.getFastPitcherChartContext(options.pitcher, options);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2159 |
const overview = result.overview ?? {};
|
| 2160 |
return {
|
| 2161 |
...result,
|
|
|
|
| 2546 |
return points.reverse();
|
| 2547 |
}
|
| 2548 |
|
| 2549 |
+
async getFastHitterChartContext(playerName, options = {}) {
|
| 2550 |
+
if (!this.hosted?.isConfigured?.()) {
|
| 2551 |
+
const fallback = await this.getPlayerContext({
|
| 2552 |
+
...options,
|
| 2553 |
+
player: playerName,
|
| 2554 |
+
playerType: 'hitter',
|
| 2555 |
+
});
|
| 2556 |
+
if (fallback.playerType !== 'hitter') {
|
| 2557 |
+
throw new Error(`No hitter matchup profile matched "${playerName}".`);
|
| 2558 |
+
}
|
| 2559 |
+
return fallback;
|
| 2560 |
+
}
|
| 2561 |
+
|
| 2562 |
+
const result = await this.hosted.buildHostedHitterParityBase(options);
|
| 2563 |
+
const hitterMatch = findBestPlayerMatch(result.rows, 'hitter_name', playerName);
|
| 2564 |
+
if (!hitterMatch) {
|
| 2565 |
+
throw new Error(`No hitter matchup profile matched "${playerName}".`);
|
| 2566 |
+
}
|
| 2567 |
+
|
| 2568 |
+
return {
|
| 2569 |
+
source: result.source,
|
| 2570 |
+
resolvedDate: result.resolvedDate,
|
| 2571 |
+
playerType: 'hitter',
|
| 2572 |
+
name: hitterMatch.hitter_name,
|
| 2573 |
+
team: hitterMatch.team ?? null,
|
| 2574 |
+
opponentTeam: hitterMatch.opponent_team ?? null,
|
| 2575 |
+
opposingPitcherName: hitterMatch.opposing_pitcher_name ?? null,
|
| 2576 |
+
hand: hitterMatch.opposing_pitcher_hand ?? null,
|
| 2577 |
+
overview: hitterMatch,
|
| 2578 |
+
};
|
| 2579 |
+
}
|
| 2580 |
+
|
| 2581 |
+
async getFastPitcherChartContext(playerName, options = {}) {
|
| 2582 |
+
if (!this.hosted?.isConfigured?.()) {
|
| 2583 |
+
const fallback = await this.getPlayerContext({
|
| 2584 |
+
...options,
|
| 2585 |
+
player: playerName,
|
| 2586 |
+
playerType: 'pitcher',
|
| 2587 |
+
});
|
| 2588 |
+
if (fallback.playerType !== 'pitcher') {
|
| 2589 |
+
throw new Error(`No pitcher matchup profile matched "${playerName}".`);
|
| 2590 |
+
}
|
| 2591 |
+
return fallback;
|
| 2592 |
+
}
|
| 2593 |
+
|
| 2594 |
+
const targetDate = parseDateOrToday(options.date);
|
| 2595 |
+
const resolvedDate = await this.hosted.getLatestAvailableDate(targetDate);
|
| 2596 |
+
if (!resolvedDate) {
|
| 2597 |
+
throw new Error('No hosted pitcher slate was available in the fallback window.');
|
| 2598 |
+
}
|
| 2599 |
+
|
| 2600 |
+
const cacheKey = this.buildChartCacheKey('pitcher-chart-base', { date: resolvedDate });
|
| 2601 |
+
const base = await this.getCachedChartValue(cacheKey, async () => {
|
| 2602 |
+
const [slateRows, pitcherRows, rosterRows] = await Promise.all([
|
| 2603 |
+
this.hosted.readDailyFile(resolvedDate, 'slate.parquet', SLATE_COLUMNS),
|
| 2604 |
+
this.hosted.readDailyFile(resolvedDate, 'daily_pitcher_metrics.parquet', PITCHER_COLUMNS),
|
| 2605 |
+
this.hosted.readDailyFile(resolvedDate, 'rosters.parquet', ROSTER_COLUMNS).catch(() => []),
|
| 2606 |
+
]);
|
| 2607 |
+
const slateLookup = mapSlateTeams(slateRows);
|
| 2608 |
+
const rosterLookup = buildRosterLookup(rosterRows);
|
| 2609 |
+
return pitcherRows
|
| 2610 |
+
.filter(keepRowForDefaults)
|
| 2611 |
+
.map((row) => withDefaults(row, slateLookup, { rosterLookup, playerType: 'pitcher' }));
|
| 2612 |
+
});
|
| 2613 |
+
|
| 2614 |
+
const pitcherMatch = findBestPlayerMatch(base, 'pitcher_name', playerName);
|
| 2615 |
+
if (!pitcherMatch) {
|
| 2616 |
+
throw new Error(`No pitcher matchup profile matched "${playerName}".`);
|
| 2617 |
+
}
|
| 2618 |
+
|
| 2619 |
+
return {
|
| 2620 |
+
source: 'hosted',
|
| 2621 |
+
resolvedDate,
|
| 2622 |
+
playerType: 'pitcher',
|
| 2623 |
+
name: pitcherMatch.pitcher_name,
|
| 2624 |
+
team: pitcherMatch.team ?? null,
|
| 2625 |
+
opponentTeam: pitcherMatch.opponent_team ?? null,
|
| 2626 |
+
hand: pitcherMatch.p_throws ?? null,
|
| 2627 |
+
overview: pitcherMatch,
|
| 2628 |
+
};
|
| 2629 |
+
}
|
| 2630 |
+
|
| 2631 |
async enrichHostedHitters(result, options = {}, methodName = 'getTopHitters') {
|
| 2632 |
if (!result?.rows?.length || !this.fallback?.getHitterSnapshotRows) {
|
| 2633 |
return result;
|