Codex commited on
Commit ·
3bbd6f4
1
Parent(s): e4fef26
Speed up hitter profile chart lookups
Browse files- src/matchups.js +35 -4
src/matchups.js
CHANGED
|
@@ -2559,15 +2559,46 @@ export class MatchupService {
|
|
| 2559 |
return fallback;
|
| 2560 |
}
|
| 2561 |
|
| 2562 |
-
const
|
| 2563 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2564 |
if (!hitterMatch) {
|
| 2565 |
throw new Error(`No hitter matchup profile matched "${playerName}".`);
|
| 2566 |
}
|
| 2567 |
|
| 2568 |
return {
|
| 2569 |
-
source:
|
| 2570 |
-
resolvedDate
|
| 2571 |
playerType: 'hitter',
|
| 2572 |
name: hitterMatch.hitter_name,
|
| 2573 |
team: hitterMatch.team ?? null,
|
|
|
|
| 2559 |
return fallback;
|
| 2560 |
}
|
| 2561 |
|
| 2562 |
+
const targetDate = parseDateOrToday(options.date);
|
| 2563 |
+
const resolvedDate = await this.hosted.getLatestAvailableDate(targetDate);
|
| 2564 |
+
if (!resolvedDate) {
|
| 2565 |
+
throw new Error('No hosted hitter slate was available in the fallback window.');
|
| 2566 |
+
}
|
| 2567 |
+
|
| 2568 |
+
const cacheKey = this.buildChartCacheKey('hitter-chart-base', { date: resolvedDate });
|
| 2569 |
+
const base = await this.getCachedChartValue(cacheKey, async () => {
|
| 2570 |
+
const [slateRows, hitterRows, pitcherRows, rosterRows] = await Promise.all([
|
| 2571 |
+
this.hosted.readDailyFile(resolvedDate, 'slate.parquet', SLATE_COLUMNS),
|
| 2572 |
+
this.hosted.readDailyFile(resolvedDate, 'daily_hitter_metrics.parquet', HITTER_COLUMNS),
|
| 2573 |
+
this.hosted.readDailyFile(resolvedDate, 'daily_pitcher_metrics.parquet', PITCHER_COLUMNS),
|
| 2574 |
+
this.hosted.readDailyFile(resolvedDate, 'rosters.parquet', ROSTER_COLUMNS).catch(() => []),
|
| 2575 |
+
]);
|
| 2576 |
+
const rosterLookup = buildRosterLookup(rosterRows);
|
| 2577 |
+
const pitcherLookup = new Map(
|
| 2578 |
+
pitcherRows
|
| 2579 |
+
.filter((row) => keepRowForDefaults(row))
|
| 2580 |
+
.map((row) => [String(row.pitcher_id ?? row.player_id ?? ''), row])
|
| 2581 |
+
);
|
| 2582 |
+
const slateLookup = mapSlateTeams(slateRows);
|
| 2583 |
+
for (const [team, slate] of slateLookup.entries()) {
|
| 2584 |
+
const pitcher = pitcherLookup.get(String(slate.opposingPitcherId ?? ''));
|
| 2585 |
+
if (pitcher?.p_throws) {
|
| 2586 |
+
slateLookup.set(team, { ...slate, opposingPitcherHand: pitcher.p_throws });
|
| 2587 |
+
}
|
| 2588 |
+
}
|
| 2589 |
+
return hitterRows
|
| 2590 |
+
.filter((row) => keepRowForDefaults(row))
|
| 2591 |
+
.map((row) => withDefaults(row, slateLookup, { rosterLookup, playerType: 'hitter' }));
|
| 2592 |
+
});
|
| 2593 |
+
|
| 2594 |
+
const hitterMatch = findBestPlayerMatch(base, 'hitter_name', playerName);
|
| 2595 |
if (!hitterMatch) {
|
| 2596 |
throw new Error(`No hitter matchup profile matched "${playerName}".`);
|
| 2597 |
}
|
| 2598 |
|
| 2599 |
return {
|
| 2600 |
+
source: 'hosted',
|
| 2601 |
+
resolvedDate,
|
| 2602 |
playerType: 'hitter',
|
| 2603 |
name: hitterMatch.hitter_name,
|
| 2604 |
team: hitterMatch.team ?? null,
|