Skip to main content
Breaking in 4.0.0
  • Integer id columns are decimal strings — Every id column of integers (id, *_id, game_pk, playerId, …) comes back as exact decimal strings on every surface — parsers, producers, loaders, HockeyTech analytics. Compare and join ids as strings; Number(row.game_id) for a safe number back. (changelog)
  • 400 / 422 raise InvalidParameterError — For every family (it was AssetFetchError), never retried; the message names host, path and status with a redacted excerpt of the body. (changelog)
  • Typed returns — generated row types for parsed: true — TypeScript only. A wrapper's raw payload resolves to unknown (was any); verified endpoints resolve to their row interfaces; the summary dispatchers to ParsedTables. Narrow or cast a raw payload. (changelog)
  • Wrapper failures raise NoDataError / AssetFetchError — Instead of raw axios errors. NoDataError = the fetch worked and there is nothing there (404, ESPN { code: 404 }); AssetFetchError = the fetch failed (403 / 429 / 5xx after retries, network). Retries follow DEFAULT_RETRY_STATUSES with backoff. (changelog)

Analytics

Not data functions

These utilities never fetch a provider payload by themselves — they transform, classify, configure or look things up. The data surface (every espn* / native wrapper and load* loader) is under ESPN Reference.

Pure frame-to-frame hockey analytics (shifts, on-ice, strength state, Corsi/Fenwick) and their league-parameterised fetch-and-enrich wrappers.

Exportkindmodule
parse_shiftsfunctionsrc/analytics/hockeytech.ts
parse_pbpfunctionsrc/analytics/hockeytech.ts
mmss_to_secondsfunctionsrc/analytics/hockeytech.ts
add_clock_columnsfunctionsrc/analytics/hockeytech.ts
add_coord_transformsfunctionsrc/analytics/hockeytech.ts
add_shot_distance_anglefunctionsrc/analytics/hockeytech.ts
NHL_SIZE_RINK_GOAL_Xconstsrc/analytics/hockeytech.ts
scoring_chancesfunctionsrc/analytics/hockeytech.ts
build_on_icefunctionsrc/analytics/hockeytech.ts
GOAL_EPSILON_Sconstsrc/analytics/hockeytech.ts
add_strength_statefunctionsrc/analytics/hockeytech.ts
corsi_fenwickfunctionsrc/analytics/hockeytech.ts
corsi_fenwick_on_icefunctionsrc/analytics/hockeytech.ts
backfill_power_playfunctionsrc/analytics/hockeytech.ts
enrich_pbpfunctionsrc/analytics/hockeytech.ts
EnrichOptionstypesrc/analytics/hockeytech.ts
per60functionsrc/analytics/hockeytech.ts
player_toifunctionsrc/analytics/hockeytech.ts
game_corsi_rowsfunctionsrc/analytics/hockeytech.ts
hockeytechShiftStintsfunctionsrc/analytics/hockeytech_family.ts
hockeytechPlayerToifunctionsrc/analytics/hockeytech_family.ts
hockeytechEnrichedPbpfunctionsrc/analytics/hockeytech_family.ts
hockeytechGameCorsifunctionsrc/analytics/hockeytech_family.ts
buildHockeytechAnalyticsfunctionsrc/analytics/hockeytech_family.ts
allHockeytechAnalyticsfunctionsrc/analytics/hockeytech_family.ts
HockeytechAnalyticstypesrc/analytics/hockeytech_family.ts

src/analytics/hockeytech.ts​

Pure HockeyTech frame functions (ports of sdv-py hockeytech/_analytics.py): parse shifts and play-by-play, attach clocks, coordinates, on-ice players, strength state, Corsi/Fenwick and time on ice. No fetching — every function takes rows and returns rows.

Import: import { … } from 'sportsdataverse/dist/analytics/hockeytech.js'

parse_shifts​

A modulekit/gameshifts payload -> one row per player-shift stint (the shift clock counts down).

export function parse_shifts(payload: unknown, game_id: unknown

parse_pbp​

A gameCenterPlayByPlay payload -> one row per event, in the hockeytech_a (850x400) or hockeytech_b (600x300) coordinate dialect.

export function parse_pbp(payload: unknown, pbp_style: string

mmss_to_seconds​

"M:SS" -> seconds, or null.

export function mmss_to_seconds(value: unknown): number | null

add_clock_columns​

Add minute_start / second_start / clock / sec_from_start from time_of_period.

export function add_clock_columns(pbp: Row[]): Row[]

add_coord_transforms​

Add the ten normalised coordinate columns (*_original, *_neutral, *_fixed, *_right, *_vertical) from x_coord / y_coord.

export function add_coord_transforms(pbp: Row[]): Row[]

add_shot_distance_angle​

Add shot distance (ft) and angle from the fixed coordinates, against a goal line at goal_x.

export function add_shot_distance_angle(pbp: Row[], goal_x: number

NHL_SIZE_RINK_GOAL_X​

The goal line's x on an NHL-sized rink (89 ft).

export const NHL_SIZE_RINK_GOAL_X

scoring_chances​

Flag scoring chances — shot attempts within threshold_ft of the goal.

export function scoring_chances(pbp: Row[], threshold_ft: number

build_on_ice​

Attach on_ice_home / on_ice_away (comma-joined player ids) to every event from the shift stints.

export function build_on_ice(pbp: Row[], shifts: Row[], goal_epsilon_s: number

GOAL_EPSILON_S​

The seconds of slack a goal gets when matched to a shift boundary (2).

export const GOAL_EPSILON_S

add_strength_state​

skaters_home / skaters_away, strength_state ("5v4", home first) and strength_state_valid from the on-ice lists.

export function add_strength_state(pbp: Row[], goalie_ids: Iterable<unknown> | null

corsi_fenwick​

Team-level CF/CA/CF%, FF/FA/FF% — one row per team.

export function corsi_fenwick(pbp: Row[]): Row[]

corsi_fenwick_on_ice​

Player-level on-ice CF/CA/FF/FA from an enriched play-by-play.

export function corsi_fenwick_on_ice(pbp: Row[]): Row[]

backfill_power_play​

Back-fill power_play / short_handed on shot and faceoff events inside a power-play window.

export function backfill_power_play(df: Row[]): Row[]

enrich_pbp​

The whole enrichment — game-meta columns, coordinates, clocks, power-play back-fill, shot geometry, on-ice and strength state (sdv-py enrich_pbp).

export function enrich_pbp(df: Row[], league: string, game_id: unknown, opts: EnrichOptions

EnrichOptions​

Options of enrich_pbp — shifts, goalie ids, coordinate dialect.

export interface EnrichOptions

per60​

A rate per 60 minutes from a count and seconds of ice time.

export function per60(value: number, toi_seconds: number): number

player_toi​

Per-player toi_seconds, num_shifts, avg_shift_s from a shifts frame.

export function player_toi(shifts: Row[]): Row[]

game_corsi_rows​

Player-level on-ice Corsi/Fenwick joined to time on ice (the body of \<lg\>_game_corsi).

export function game_corsi_rows(enrichedPbp: Row[], shifts: Row[]): Row[]

src/analytics/hockeytech_family.ts​

The league-parameterised HockeyTech analytics — fetch a game's shifts and play-by-play, then run the pure frame functions. Mounted on sdv.hockeytech as hockeytech_shift_stints / hockeytech_player_toi / hockeytech_enriched_pbp / hockeytech_game_corsi and, per league, \<lg\>_game_shifts / \<lg\>_player_toi / \<lg\>_pbp / \<lg\>_game_corsi.

Mounted on: sdv.hockeytech (snake_case name + camelCase alias).

hockeytechShiftStints​

A game's shift stints (sdv-py \<lg\>_game_shifts).

export async function hockeytechShiftStints(league: string, gameId: GameId): Promise<Row[]>

Aliases: hockeytech_shift_stints

Example:

const stints = await sdv.hockeytech.hockeytech_shift_stints({ league: 'pwhl', game_id: 42 });

hockeytechPlayerToi​

A game's per-player time on ice (sdv-py \<lg\>_player_toi).

export async function hockeytechPlayerToi(league: string, gameId: GameId): Promise<Row[]>

Aliases: hockeytech_player_toi

hockeytechEnrichedPbp​

A game's enriched play-by-play (sdv-py \<lg\>_pbp).

export async function hockeytechEnrichedPbp(league: string, gameId: GameId): Promise<Row[]>

Aliases: hockeytech_enriched_pbp

hockeytechGameCorsi​

A game's player-level on-ice Corsi/Fenwick with time on ice (sdv-py \<lg\>_game_corsi).

export async function hockeytechGameCorsi(league: string, gameId: GameId): Promise<Row[]>

Aliases: hockeytech_game_corsi

buildHockeytechAnalytics​

The three per-league callables (\<lg\>_game_shifts, \<lg\>_player_toi, \<lg\>_game_corsi) for one league slug.

export function buildHockeytechAnalytics(league: string): Record<string, (gameId: GameId)

allHockeytechAnalytics​

Every league's analytics callables, keyed by name — what sdv.hockeytech mounts.

export function allHockeytechAnalytics(): HockeytechAnalytics

HockeytechAnalytics​

The type of allHockeytechAnalytics().

export type HockeytechAnalytics =

Generated by tools/codegen/generate.mjs from tools/codegen/utilities.yaml — see How this library is built.