@sensiblestats/widget-sdk 0.75.0 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/index.cjs +13 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +170 -9
- package/dist/index.d.ts +170 -9
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/eventLog.ts","../src/client.ts","../src/matchKey.ts","../src/types.ts","../src/sports.ts"],"sourcesContent":["export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\n// B4 Q7: the codes a brand's limit refuses with. Any other 429 stays a plain RateLimitError.\nexport const LIMIT_CODES = ['daily_cap', 'quota_exhausted', 'assistant_paused'] as const\nexport type LimitCode = (typeof LIMIT_CODES)[number]\nexport function isLimitCode(code: unknown): code is LimitCode {\n return typeof code === 'string' && (LIMIT_CODES as readonly string[]).includes(code)\n}\nexport interface LimitDetails {\n limitCode: LimitCode\n resetsAt?: string\n /** The brand's or the built-in text, already in the user's language. */\n message?: string\n}\nexport class LimitError extends RateLimitError {\n readonly limitCode: LimitCode\n readonly resetsAt?: string\n readonly limitMessage?: string\n constructor(details: LimitDetails, retryAfter?: number) {\n super(retryAfter, details.message ?? 'Limit reached')\n this.limitCode = details.limitCode\n this.resetsAt = details.resetsAt\n this.limitMessage = details.message\n }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, isLimitCode, LimitError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type {\n BuilderGridPayload, BuilderGridRequest, ClubFanDashboardPayload, ClubFixturesPayload, ClubSquadPayload, ClubSquadStatsPayload, ClubPlayerDetailPayload, ClubRecordsPayload, ClubStandingsPayload, GameListPayload, GameResultPayload, GameStatePayload, LeaderboardPayload,\n FavouriteEntity, FavouriteKind, FavouritesNoIdentity, FavouritesPayload, FavouriteStarResponse, LeagueStarResult, LiveMonitorSnapshot, MarketOddsBlock, PinRef, PlayerPropsBundle, PresetGrid, PresetGridOptions, SchedulePayload, StatesPayload, SubmitPlayBody, SubmitPlayResult,\n} from './events'\nimport type { SlipSport } from './sports'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n client?: string\n}\n\nexport function headersFor(cfg: ResolvedConfig, json: boolean): Record<string, string> {\n const h: Record<string, string> = json ? { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey } : { 'X-SS-Public-Key': cfg.publicKey }\n if (cfg.client) h['X-SS-Client'] = cfg.client\n return h\n}\n\nconst OPERATOR_USER_ID_HEADER = 'X-SS-Operator-User-Id'\nconst ANONYMOUS_USER_ID_HEADER = 'X-SS-Anonymous-User-Id'\n\n// Same rule as the gateway's VisitorIdHeaders.IsValid: printable ASCII, 1 to 128 characters.\nconst SENDABLE_ID = /^[\\x20-\\x7E]{1,128}$/\n\n// Visitor ids travel in these two headers on every gateway call, never in the query string or the JSON\n// body. The trimmed id is sent (fetch strips edge whitespace anyway). An id that is blank or that the\n// gateway would reject is left out like a blank one, so a bad id can never make fetch throw.\nexport function isSendableId(id?: string): boolean {\n const v = id?.trim()\n return !!v && SENDABLE_ID.test(v)\n}\n\nexport function identityHeaders(operatorUserId?: string, anonymousUserId?: string): Record<string, string> {\n const h: Record<string, string> = {}\n if (isSendableId(operatorUserId)) h[OPERATOR_USER_ID_HEADER] = operatorUserId!.trim()\n if (isSendableId(anonymousUserId)) h[ANONYMOUS_USER_ID_HEADER] = anonymousUserId!.trim()\n return h\n}\n\ninterface BodyIds { operatorUserId?: string; anonymousUserId?: string }\n\nfunction splitIdentity(body: object): { identity: Record<string, string>; rest: Record<string, unknown> } {\n const { operatorUserId, anonymousUserId, ...rest } = body as BodyIds & Record<string, unknown>\n return { identity: identityHeaders(operatorUserId, anonymousUserId), rest }\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\n// B4 Q7: a limit refusal is a 429 whose problem+json body names the limit. The gateway's own per-minute 429 sets\n// Retry-After without exposing it to browsers, so a missing header is normal: the body's retryAfterSeconds covers\n// it, and no countdown is shown when neither is present.\nexport async function chatError(res: Response): Promise<WidgetSdkError> {\n const base = toWidgetError(res.status, res.headers.get('Retry-After'))\n if (!(base instanceof RateLimitError)) return base\n let body: unknown\n try { body = await res.json() } catch { return base }\n if (typeof body !== 'object' || body === null) return base\n const b = body as Record<string, unknown>\n if (!isLimitCode(b.errorCode)) return base\n const text = (v: unknown): string | undefined => (typeof v === 'string' && v.trim() !== '' ? v : undefined)\n const header = res.headers.get('Retry-After')?.trim()\n const headerRetry = header != null && /^\\d+$/.test(header) ? Number(header) : undefined\n const bodyRetry = typeof b.retryAfterSeconds === 'number' && Number.isFinite(b.retryAfterSeconds) && b.retryAfterSeconds >= 0 ? b.retryAfterSeconds : undefined\n return new LimitError(\n { limitCode: b.errorCode, resetsAt: text(b.resetsAt), message: text(b.message) },\n headerRetry ?? bodyRetry,\n )\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(\n cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal, identity: Record<string, string> = {},\n): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const { userContext, ...rest } = input\n let body: object = rest\n let identity: Record<string, string> = {}\n if (userContext) {\n const split = splitIdentity(userContext)\n identity = split.identity\n body = Object.keys(split.rest).length > 0 ? { ...rest, userContext: split.rest } : rest\n }\n const res = await send(cfg, 'chat', body, signal, identity)\n if (!res.ok || res.body == null) throw await chatError(res)\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const { identity, rest } = splitIdentity(wireBody)\n const res = await send(cfg, 'signals', rest, signal, identity)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n\nexport async function postEvents(cfg: ResolvedConfig, batch: object): Promise<void> {\n const { identity, rest } = splitIdentity(batch)\n const res = await send(cfg, 'events', rest, undefined, identity)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n\n// Best-effort tail flush on page hide/unload. Uses fetch keepalive (not sendBeacon) because the\n// gateway requires the X-SS-Public-Key header, which sendBeacon cannot set. Both the synchronous\n// call and the returned promise are guarded -- an async rejection (real network failure, or\n// Chrome's ~64KB keepalive body cap) must never surface as an unhandled rejection, since this\n// runs inside an operator-embedded widget during page-hide and would show up as noise in the\n// OPERATOR's own error monitoring.\nexport function postEventsKeepalive(cfg: ResolvedConfig, batch: object): void {\n try {\n const { identity, rest } = splitIdentity(batch)\n void cfg.fetch(endpoint(cfg, 'events'), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(rest),\n keepalive: true,\n }).catch(() => { /* best-effort tail flush -- swallow async rejection too */ })\n } catch {\n /* best-effort tail flush -- never throw on unload */\n }\n}\n\nexport async function getLiveDashboard(cfg: ResolvedConfig): Promise<ClubFanDashboardPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-dashboard'), { method: 'GET', headers: headersFor(cfg, false) })\n // 204 is the definitive \"not live / match over\" signal -- the poll loop stops on it.\n // Any other non-ok status (e.g. a transient 502/503/504) must throw rather than return\n // null, so the poll loop's per-tick try/catch retries on the next tick instead of stopping.\n if (res.status === 204) return null\n if (!res.ok) throw new Error(`live-dashboard ${res.status}`)\n return (await res.json()) as ClubFanDashboardPayload\n}\n\n// 404 is the definitive \"live monitor disabled for this operator\" signal -- the poll loop\n// stops and the tabs disable. Any other non-ok status must throw so the per-tick\n// try/catch retries next tick instead of silently disabling the feature.\nexport async function postLiveMonitor(cfg: ResolvedConfig, pins: PinRef[], locale?: string): Promise<LiveMonitorSnapshot | null> {\n const body: { pins: PinRef[]; locale?: string } = { pins }\n if (locale) body.locale = locale\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(body),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor ${res.status}`)\n return (await res.json()) as LiveMonitorSnapshot\n}\n\nexport async function postMarketOdds(\n cfg: ResolvedConfig, matchId: number, marketDeveloperName: string, sport?: SlipSport,\n): Promise<MarketOddsBlock | null> {\n const body: { matchId: number; marketDeveloperName: string; sport?: SlipSport } = { matchId, marketDeveloperName }\n if (sport) body.sport = sport\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/market'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(body),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/market ${res.status}`)\n return (await res.json()) as MarketOddsBlock\n}\n\nexport async function postPlayerProps(cfg: ResolvedConfig, matchId: number, sport?: 'americanfootball'): Promise<PlayerPropsBundle | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/props'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(sport ? { matchId, sport } : { matchId }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/props ${res.status}`)\n return (await res.json()) as PlayerPropsBundle\n}\n\n// 404 mirrors postLiveMonitor: the definitive \"live monitor disabled for this operator\" signal.\n// Every other non-ok status throws so the caller's per-tick catch retries next tick.\nexport async function postSchedule(\n cfg: ResolvedConfig, localDate: string, utcOffsetMinutes: number,\n operatorUserId?: string, anonymousUserId?: string,\n): Promise<SchedulePayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/schedule'), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identityHeaders(operatorUserId, anonymousUserId) },\n body: JSON.stringify({ localDate, utcOffsetMinutes, sports: ['basketball', 'americanfootball'] }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/schedule ${res.status}`)\n return (await res.json()) as SchedulePayload\n}\n\nexport async function postLeagueStar(\n cfg: ResolvedConfig, competitionId: number, starred: boolean,\n operatorUserId?: string, anonymousUserId?: string,\n): Promise<LeagueStarResult | null> {\n const res = await cfg.fetch(endpoint(cfg, `leagues/${competitionId}/star`), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identityHeaders(operatorUserId, anonymousUserId) },\n body: JSON.stringify({ starred }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`leagues/star ${res.status}`)\n return (await res.json()) as LeagueStarResult\n}\n\nexport async function postStates(\n cfg: ResolvedConfig, matchIds: number[], nbaGameIds?: number[], nflGameIds?: number[],\n): Promise<StatesPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/states'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify({\n matchIds,\n ...(nbaGameIds?.length ? { nbaGameIds } : {}),\n ...(nflGameIds?.length ? { nflGameIds } : {}),\n }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/states ${res.status}`)\n return (await res.json()) as StatesPayload\n}\n\nfunction q(parts: Record<string, string | number | undefined>): string {\n const kept = Object.entries(parts)\n .filter(([, v]) => v !== undefined && v !== '')\n .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)\n return kept.length ? `?${kept.join('&')}` : ''\n}\n\nexport async function getGames(cfg: ResolvedConfig, operatorUserId?: string, gameDay?: string): Promise<GameListPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'games' + q({ gameDay })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`games ${res.status}`)\n return (await res.json()) as GameListPayload\n}\n\nexport async function getGameConfig(cfg: ResolvedConfig, gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameStatePayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}` + q({ fixtureId, gameDay, locale })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`game-config ${res.status}`)\n return (await res.json()) as GameStatePayload\n}\n\nexport async function getGameResult(cfg: ResolvedConfig, gameId: string, operatorUserId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameResultPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}/result` + q({ fixtureId, gameDay, locale })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`game-result ${res.status}`)\n return (await res.json()) as GameResultPayload\n}\n\nexport async function postPlay(cfg: ResolvedConfig, gameId: string, body: SubmitPlayBody, locale?: string): Promise<SubmitPlayResult | null> {\n const { identity, rest } = splitIdentity(body)\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}/plays` + q({ locale })), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(rest),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`play ${res.status}`)\n return (await res.json()) as SubmitPlayResult\n}\n\nexport async function getLeaderboard(cfg: ResolvedConfig, operatorUserId?: string, week?: string): Promise<LeaderboardPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'games/leaderboard' + q({ week })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`leaderboard ${res.status}`)\n return (await res.json()) as LeaderboardPayload\n}\n\nexport async function getClubFixtures(cfg: ResolvedConfig, competitionId?: number, limit?: number): Promise<ClubFixturesPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/fixtures' + q({ competitionId, limit })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-fixtures ${res.status}`)\n return (await res.json()) as ClubFixturesPayload\n}\n\nexport async function getClubStandings(cfg: ResolvedConfig, competitionId?: number): Promise<ClubStandingsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/standings' + q({ competitionId })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-standings ${res.status}`)\n return (await res.json()) as ClubStandingsPayload\n}\n\nexport async function getClubSquad(cfg: ResolvedConfig): Promise<ClubSquadPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/squad'), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-squad ${res.status}`)\n return (await res.json()) as ClubSquadPayload\n}\n\nexport async function getClubSquadStats(cfg: ResolvedConfig): Promise<ClubSquadStatsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/squad/stats'), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-squad-stats ${res.status}`)\n return (await res.json()) as ClubSquadStatsPayload\n}\n\nexport async function getClubPlayerDetail(cfg: ResolvedConfig, playerId: number): Promise<ClubPlayerDetailPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `club/player/${encodeURIComponent(String(playerId))}`), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-player ${res.status}`)\n return (await res.json()) as ClubPlayerDetailPayload\n}\n\nexport async function getClubRecords(cfg: ResolvedConfig, limit?: number): Promise<ClubRecordsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/records' + q({ limit })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-records ${res.status}`)\n return (await res.json()) as ClubRecordsPayload\n}\n\n// Onboarding presets stage 2 (contract §1). 404 is the definitive \"no presets for this visitor\"\n// answer (flag off, not a betting operator, or cool-off). 503 and every other non-ok status throw:\n// the widget keeps any grid it already has and asks again on the next panel open.\n// operatorUserId is optional, sent as the games routes send it (in its header): the cool-off check (D3)\n// needs it, and a request without it is an anonymous visitor.\nexport async function getPricePresets(\n cfg: ResolvedConfig, locale: string, operatorUserId?: string, options?: PresetGridOptions,\n): Promise<PresetGrid | null> {\n const res = await cfg.fetch(endpoint(cfg, 'price-presets' + q({ locale, pool: options?.pool })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`price-presets ${res.status}`)\n return (await res.json()) as PresetGrid\n}\n\n// 404 is the cool-off / non-betting-operator answer, as getPricePresets. Identity travels in headers only, never the query.\nexport async function getBuilderGrid(\n cfg: ResolvedConfig, locale: string, req: BuilderGridRequest,\n): Promise<BuilderGridPayload | null> {\n const query = q({\n locale,\n sport: req.sport,\n legs: req.legs,\n total: req.total,\n marketKey: req.marketKey ?? undefined,\n matchIds: req.widen ? undefined : req.matchIds.join(','),\n widen: req.widen ? 'true' : undefined,\n })\n const res = await cfg.fetch(endpoint(cfg, 'price-presets' + query), {\n method: 'GET',\n headers: { ...headersFor(cfg, false), ...identityHeaders(req.operatorUserId, req.anonymousUserId) },\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`price-presets ${res.status}`)\n return (await res.json()) as BuilderGridPayload\n}\n\n// Favourites routes carry identity in headers only and send no body. A non-ok answer, including the\n// gateway's 429 TooManyVisitorIds, resolves the call's failure value; only a transport failure throws.\nfunction favouritePath(kind: FavouriteKind, id: string): string {\n return `favourites/${encodeURIComponent(kind)}/${encodeURIComponent(id)}`\n}\n\nfunction favouritesFetch(\n cfg: ResolvedConfig, method: 'GET' | 'PUT' | 'POST' | 'DELETE', path: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<Response> {\n return cfg.fetch(endpoint(cfg, path), { method, headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId, anonymousUserId) } })\n}\n\nexport async function getFavourites(\n cfg: ResolvedConfig, sport: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouritesPayload | FavouritesNoIdentity | null> {\n const res = await favouritesFetch(cfg, 'GET', 'favourites' + q({ sport }), operatorUserId, anonymousUserId)\n if (res.status === 400) {\n const body = (await res.json().catch(() => null)) as { code?: string } | null\n return body?.code === 'NoAcceptedIdentity' ? 'noAcceptedIdentity' : null\n }\n if (!res.ok) return null\n return (await res.json()) as FavouritesPayload\n}\n\nconst MIN_FAVOURITES_QUERY = 2\n\nexport async function searchFavourites(\n cfg: ResolvedConfig, sport: string, query: string, kind: FavouriteKind, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouriteEntity[] | null> {\n const text = query.trim()\n if (text.length < MIN_FAVOURITES_QUERY) return []\n const res = await favouritesFetch(cfg, 'GET', 'favourites/search' + q({ sport, q: text, kind }), operatorUserId, anonymousUserId)\n if (!res.ok) return null\n return ((await res.json()) as { results: FavouriteEntity[] }).results\n}\n\n// A 409 whose body says atCap is an answer, not a failure: it carries the count and cap.\nexport async function putFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouriteStarResponse | null> {\n const res = await favouritesFetch(cfg, 'PUT', favouritePath(kind, id), operatorUserId, anonymousUserId)\n if (res.ok) return (await res.json()) as FavouriteStarResponse\n if (res.status !== 409) return null\n const body = (await res.json().catch(() => null)) as { status?: string; count?: number; cap?: number } | null\n return body?.status === 'atCap' ? { status: 'atCap', count: body.count, cap: body.cap } : null\n}\n\nexport async function deleteFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'DELETE', favouritePath(kind, id), operatorUserId, anonymousUserId)).ok\n}\n\nexport async function clearFavourites(\n cfg: ResolvedConfig, sport: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'DELETE', 'favourites' + q({ sport }), operatorUserId, anonymousUserId)).ok\n}\n\n// 404 NotLearned and 409 Starred are not ok, so both resolve false.\nexport async function hideFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'POST', `${favouritePath(kind, id)}/hide`, operatorUserId, anonymousUserId)).ok\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName?: string; entityId?: string\n operatorUserId?: string; anonymousUserId?: string; dashboardLayout?: string; tileIndex?: number\n sport?: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return {\n signalType, entityType, entityName: input.entityName, entityId: input.entityId,\n operatorUserId: input.operatorUserId, anonymousUserId: input.anonymousUserId,\n dashboardLayout: input.dashboardLayout, tileIndex: input.tileIndex, sport: input.sport,\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport type {\n BuilderGridPayload, BuilderGridRequest, ClubFanDashboardPayload, ClubFixturesPayload, ClubSquadPayload, ClubSquadStatsPayload, ClubPlayerDetailPayload, ClubRecordsPayload, ClubStandingsPayload, GameListPayload, GameResultPayload, GameStatePayload, LeaderboardPayload,\n FavouriteEntity, FavouriteKind, FavouritesNoIdentity, FavouritesPayload, FavouriteStarResponse, LeagueStarResult, LiveMonitorSnapshot, MarketOddsBlock, PinRef, PlayerPropsBundle, PresetGrid, PresetGridOptions, SchedulePayload, StatesPayload, SubmitPlayResult,\n} from './events'\nimport {\n clearFavourites, deleteFavourite, getFavourites, hideFavourite, putFavourite, searchFavourites,\n getClubFixtures, getClubPlayerDetail, getClubRecords, getClubSquad, getClubSquadStats, getClubStandings, getGameConfig, getGameResult, getGames, getLeaderboard, getLiveDashboard, getBuilderGrid, getPricePresets,\n postLeagueStar, postLiveMonitor, postMarketOdds, postPlayerProps, postPlay, postSchedule, postSignal, postStates, type ResolvedConfig,\n isSendableId,\n} from './http'\nimport { toSignalWireBody } from './signals'\nimport type { SlipSport } from './sports'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: SignalInput): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n const anonymousUserId = isSendableId(operatorUserId) ? undefined : (input.anonymousUserId ?? this.context?.anonymousUserId)\n if (!operatorUserId && !anonymousUserId) {\n throw new Error('operatorUserId or anonymousUserId is required (set it on conversation() or pass it to sendSignal)')\n }\n if (!input.entityId && !input.entityName) {\n throw new Error('entityId or entityName is required')\n }\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId, anonymousUserId }))\n }\n\n getLiveDashboard(): Promise<ClubFanDashboardPayload | null> {\n return getLiveDashboard(this.cfg)\n }\n\n getLiveMonitor(pins: PinRef[], locale?: string): Promise<LiveMonitorSnapshot | null> {\n return postLiveMonitor(this.cfg, pins, locale)\n }\n\n getMarketOdds(matchId: number, marketDeveloperName: string, sport?: SlipSport): Promise<MarketOddsBlock | null> {\n return postMarketOdds(this.cfg, matchId, marketDeveloperName, sport)\n }\n\n getPlayerProps(matchId: number, sport?: 'americanfootball'): Promise<PlayerPropsBundle | null> {\n return postPlayerProps(this.cfg, matchId, sport)\n }\n\n getPricePresets(locale: string, options?: PresetGridOptions): Promise<PresetGrid | null> {\n return getPricePresets(this.cfg, locale, this.context?.operatorUserId, options)\n }\n\n getBuilderGrid(locale: string, req: BuilderGridRequest): Promise<BuilderGridPayload | null> {\n return getBuilderGrid(this.cfg, locale, req)\n }\n\n getSchedule(\n localDate: string, utcOffsetMinutes: number, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<SchedulePayload | null> {\n return postSchedule(this.cfg, localDate, utcOffsetMinutes, operatorUserId, anonymousUserId)\n }\n\n starLeague(\n competitionId: number, starred: boolean, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<LeagueStarResult | null> {\n return postLeagueStar(this.cfg, competitionId, starred, operatorUserId, anonymousUserId)\n }\n\n getFavourites(sport: string, operatorUserId?: string, anonymousUserId?: string): Promise<FavouritesPayload | FavouritesNoIdentity | null> {\n return getFavourites(this.cfg, sport, operatorUserId, anonymousUserId)\n }\n\n searchFavourites(\n sport: string, query: string, kind: FavouriteKind, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<FavouriteEntity[] | null> {\n return searchFavourites(this.cfg, sport, query, kind, operatorUserId, anonymousUserId)\n }\n\n putFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<FavouriteStarResponse | null> {\n return putFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n deleteFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return deleteFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n clearFavourites(sport: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return clearFavourites(this.cfg, sport, operatorUserId, anonymousUserId)\n }\n\n hideFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return hideFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n getStates(matchIds: number[], nbaGameIds?: number[], nflGameIds?: number[]): Promise<StatesPayload | null> {\n return postStates(this.cfg, matchIds, nbaGameIds, nflGameIds)\n }\n\n getGames(gameDay?: string): Promise<GameListPayload | null> {\n return getGames(this.cfg, this.context?.operatorUserId, gameDay)\n }\n\n getGameConfig(gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameStatePayload | null> {\n return getGameConfig(this.cfg, gameId, fixtureId, gameDay, locale)\n }\n\n getGameResult(gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameResultPayload | null> {\n const operatorUserId = this.context?.operatorUserId\n if (!operatorUserId) return Promise.resolve(null)\n return getGameResult(this.cfg, gameId, operatorUserId, fixtureId, gameDay, locale)\n }\n\n postPlay(gameId: string, answerJson: string, gameDay: string, fixtureId?: number, locale?: string): Promise<SubmitPlayResult | null> {\n const operatorUserId = this.context?.operatorUserId\n if (!operatorUserId) return Promise.resolve(null)\n return postPlay(this.cfg, gameId, { operatorUserId, gameDay, answerJson, fixtureId }, locale)\n }\n\n getLeaderboard(week?: string): Promise<LeaderboardPayload | null> {\n return getLeaderboard(this.cfg, this.context?.operatorUserId, week)\n }\n\n getClubFixtures(competitionId?: number, limit?: number): Promise<ClubFixturesPayload | null> {\n return getClubFixtures(this.cfg, competitionId, limit)\n }\n getClubStandings(competitionId?: number): Promise<ClubStandingsPayload | null> {\n return getClubStandings(this.cfg, competitionId)\n }\n getClubSquad(): Promise<ClubSquadPayload | null> {\n return getClubSquad(this.cfg)\n }\n getClubSquadStats(): Promise<ClubSquadStatsPayload | null> {\n return getClubSquadStats(this.cfg)\n }\n getClubPlayerDetail(playerId: number): Promise<ClubPlayerDetailPayload | null> {\n return getClubPlayerDetail(this.cfg, playerId)\n }\n getClubRecords(limit?: number): Promise<ClubRecordsPayload | null> {\n return getClubRecords(this.cfg, limit)\n }\n}\n","export type WidgetEntityEventName =\n | 'pin_add' | 'pin_remove' | 'slip_click' | 'slip_result'\n | 'insight_expand' | 'tile_tap' | 'chip_tap'\n | 'slip_remove' | 'bet_placed' | 'match_view' | 'match_open' | 'combo_add'\n\nexport type WidgetPopupEventName = 'popup_shown' | 'popup_opened' | 'popup_dismissed'\n\nexport type WidgetPopupAskEventName = 'popup_ask_tap'\n\nexport type WidgetOpenEventName = 'widget_open'\n\nexport type WidgetSportSwitchEventName = 'dashboard_sport_switch'\n\nexport type WidgetEventName =\n WidgetEntityEventName | WidgetPopupEventName | WidgetPopupAskEventName | WidgetOpenEventName | WidgetSportSwitchEventName\n\nexport type WidgetEntityType = 'match' | 'team' | 'player' | 'competition' | 'market'\n\n/** `totalChosen` is the visitor's total control as a string on the wire; `totalActual` is the server's total for the shown combo. */\nexport interface ComboAddMetadata {\n sport: string\n legs: number\n totalChosen: 'any' | '3' | '5' | '10' | '20' | '50'\n totalActual: number\n markets: string[]\n}\n\nexport interface WidgetEventInput {\n name: WidgetEntityEventName\n entityType: WidgetEntityType\n entityId?: string\n entityName?: string\n marketDeveloperName?: string\n outcome?: string\n /** Football match id of the slip selection (slip_click / slip_result). */\n matchId?: number\n /** The raw odds label as stored (\"Home\", \"Over\", \"Home/Draw\"), never a joined display string. Max 64. */\n selection?: string\n /** The raw line (\"2.5\"). Max 32; omit when empty. */\n line?: string\n /** Decimal price shown when the selection was added. */\n odds?: number\n /** Wire sport key ('nba'); absent means football. */\n sport?: string\n /** combo_add only: what the visitor asked for and what the server returned. */\n metadata?: ComboAddMetadata\n}\n\n/** Launcher popup telemetry: counted server-side, never tied to an entity. */\nexport type WidgetPopupEventInput =\n { name: WidgetPopupEventName } & { [K in Exclude<keyof WidgetEventInput, 'name'>]?: never }\n\n/** A tap on one of the launcher bubble's asks. `outcome` carries the ask's position, \"0\" or \"1\"\n * (contract §5): the gateway forwards only the fields of its own event model, and outcome is its\n * one free-text field. */\nexport type WidgetPopupAskEventInput =\n { name: WidgetPopupAskEventName; outcome: string } & { [K in Exclude<keyof WidgetEventInput, 'name' | 'outcome'>]?: never }\n\n/** The panel opening: entity-free, each open is added to the user's count for the day. */\nexport type WidgetOpenEventInput =\n { name: WidgetOpenEventName } & { [K in Exclude<keyof WidgetEventInput, 'name'>]?: never }\n\n/** The greeting sport switch: `outcome` is the sport switched to (a server sport key). Entity-free; the server drops an unknown outcome. */\nexport type WidgetSportSwitchEventInput =\n { name: WidgetSportSwitchEventName; outcome: string } & { [K in Exclude<keyof WidgetEventInput, 'name' | 'outcome'>]?: never }\n\nexport type WidgetLogInput =\n WidgetEventInput | WidgetPopupEventInput | WidgetPopupAskEventInput | WidgetOpenEventInput | WidgetSportSwitchEventInput\n\nexport type WireEvent = WidgetLogInput & {\n seq: number\n at: number\n}\n\nexport interface EventBatch {\n v: 1\n sessionId: string\n conversationId?: string\n operatorUserId?: string\n anonymousUserId?: string\n /**\n * Events dropped after exhausting delivery attempts during a PRIOR flush cycle — not a count of\n * this batch's own events. Rides whichever batch is built next after the drop, then is omitted\n * (0/undefined) once a clean cycle passes without a new failure.\n */\n dropped?: number\n /**\n * Failed delivery attempts from a PRIOR flush cycle — not retries of this batch's own events.\n * Rides whichever batch is built next after the failure, then is omitted (0/undefined) once a\n * clean cycle passes without a new failure.\n */\n retries?: number\n events: WireEvent[]\n}\n\nexport interface EventLoggerOptions {\n /** Normal delivery (fetch). Rejecting triggers the retry/backoff loop. */\n flush: (batch: EventBatch) => Promise<void>\n /** Best-effort tail flush on page hide/unload (fetch keepalive). Never awaited. */\n flushKeepalive: (batch: EventBatch) => void\n /** Injectable clock (tests). Defaults to Date.now. */\n now?: () => number\n batchIntervalMs?: number\n maxBatch?: number\n maxAttempts?: number\n}\n\nexport interface EventLogger {\n log(input: WidgetLogInput): void\n setIdentity(id: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): void\n flushNow(): Promise<void>\n flushOnHide(): void\n dispose(): void\n /** Undoes dispose(). React StrictMode runs an effect's cleanup and then its setup again on the\n * same logger, so the widget's setup has to be able to bring a disposed logger back. */\n resume(): void\n}\n\nconst IMMEDIATE: ReadonlySet<WidgetEventName> = new Set([\n 'pin_add', 'pin_remove', 'slip_click', 'slip_result', 'slip_remove', 'bet_placed', 'combo_add',\n])\n\n// Queued without arming the batch timer: the event leaves with the next flush of any cause. A match\n// page view fires for every visitor, so it must never start a request of its own.\nconst DEFERRED: ReadonlySet<WidgetEventName> = new Set(['match_view'])\n\nconst DEFAULT_BATCH_INTERVAL_MS = 10_000\nconst DEFAULT_MAX_BATCH = 50\nconst DEFAULT_MAX_ATTEMPTS = 3\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction makeSessionId(): string {\n const c: Crypto | undefined = globalThis.crypto\n if (c && typeof c.randomUUID === 'function') return c.randomUUID()\n return `s_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`\n}\n\nclass EventLoggerImpl implements EventLogger {\n private readonly sessionId = makeSessionId()\n private readonly now: () => number\n private readonly batchIntervalMs: number\n private readonly maxBatch: number\n private readonly maxAttempts: number\n\n private queue: WireEvent[] = []\n private seq = 0\n private retries = 0\n private dropped = 0\n private identity: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string } = {}\n private timer: ReturnType<typeof setTimeout> | null = null\n private inFlight: Promise<void> | null = null\n private disposed = false\n\n constructor(private readonly opts: EventLoggerOptions) {\n this.now = opts.now ?? (() => Date.now())\n this.batchIntervalMs = opts.batchIntervalMs ?? DEFAULT_BATCH_INTERVAL_MS\n this.maxBatch = opts.maxBatch ?? DEFAULT_MAX_BATCH\n this.maxAttempts = opts.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n }\n\n log(input: WidgetLogInput): void {\n if (this.disposed) return\n const event: WireEvent = { ...input, seq: ++this.seq, at: this.now() }\n this.queue.push(event)\n if (IMMEDIATE.has(input.name)) {\n this.trigger()\n } else if (this.queue.length >= this.maxBatch) {\n this.trigger()\n } else if (!DEFERRED.has(input.name)) {\n this.armTimer()\n }\n }\n\n setIdentity(id: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): void {\n this.identity = { ...this.identity, ...id }\n }\n\n async flushNow(): Promise<void> {\n if (this.inFlight) await this.inFlight\n if (this.queue.length > 0) await this.doFlush()\n }\n\n flushOnHide(): void {\n this.clearTimer()\n const batch = this.buildBatch()\n if (batch === null) return\n this.opts.flushKeepalive(batch)\n }\n\n dispose(): void {\n this.disposed = true\n this.clearTimer()\n }\n\n resume(): void {\n this.disposed = false\n }\n\n private armTimer(): void {\n if (this.timer !== null) return\n this.timer = setTimeout(() => {\n this.timer = null\n this.trigger()\n }, this.batchIntervalMs)\n }\n\n private clearTimer(): void {\n if (this.timer === null) return\n clearTimeout(this.timer)\n this.timer = null\n }\n\n private trigger(): void {\n if (this.disposed) return\n if (this.inFlight) return\n this.inFlight = this.doFlush().finally(() => {\n this.inFlight = null\n // An immediate (or maxBatch-triggered) log() call that arrived while this flush was\n // in-flight was a no-op above -- drain it now instead of stranding it until some later\n // log()/flushNow()/dispose() call. Guarded by the disposed check at the top of trigger()\n // itself, so a straggler queued just before dispose() does not fire a flush after it.\n if (this.queue.length > 0) this.trigger()\n })\n }\n\n /**\n * Snapshots the queue + carry-over counters (see EventBatch.dropped/retries) into a batch and\n * resets both for the next cycle. Returns null only when there is truly nothing to report --\n * an empty queue AND no pending dropped/retries -- so a pending counter-only report (queue\n * drained by an exhausted flush, nothing logged since) still gets built and delivered.\n */\n private buildBatch(): EventBatch | null {\n if (this.queue.length === 0 && this.retries === 0 && this.dropped === 0) return null\n const events = this.queue\n this.queue = []\n const batch: EventBatch = { v: 1, sessionId: this.sessionId, ...this.identity, events }\n if (this.retries > 0) batch.retries = this.retries\n if (this.dropped > 0) batch.dropped = this.dropped\n this.retries = 0\n this.dropped = 0\n return batch\n }\n\n private async doFlush(): Promise<void> {\n this.clearTimer()\n const batch = this.buildBatch()\n if (batch === null) return\n for (let attempt = 1; attempt <= this.maxAttempts; attempt++) {\n try {\n await this.opts.flush(batch)\n return\n } catch {\n this.retries++\n if (attempt >= this.maxAttempts) {\n this.dropped += batch.events.length\n return\n }\n await delay(2 ** attempt * 50)\n }\n }\n }\n}\n\nexport function createEventLogger(opts: EventLoggerOptions): EventLogger {\n return new EventLoggerImpl(opts)\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { createEventLogger, type EventLogger } from './eventLog'\nimport { postEvents, postEventsKeepalive, postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n client: options.client,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n\n createEventLogger(identity?: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): EventLogger {\n const logger = createEventLogger({\n flush: (batch) => postEvents(this.cfg, batch),\n flushKeepalive: (batch) => postEventsKeepalive(this.cfg, batch),\n })\n if (identity) logger.setIdentity(identity)\n return logger\n }\n}\n","export function matchKey(sport: string | undefined, id: number): string {\n return `${sport ?? 'football'}:${id}`\n}\n","import type { SlipSport } from './sports'\n\nexport type FetchLike = (input: string, init: RequestInit) => Promise<Response>\n\nexport interface StatsWidgetClientOptions {\n operatorId: string\n publicKey: string\n baseUrl?: string\n /** Advanced/testing: inject a fetch implementation. Defaults to globalThis.fetch. */\n fetch?: FetchLike\n /** Sent as X-SS-Client; set by widget-react. */\n client?: string\n}\n\nexport interface UserContext {\n operatorUserId?: string\n defaultLanguage?: string\n anonymousUserId?: string\n}\n\nexport interface ChatGrounding {\n kind?: string\n matchId?: number\n opponentTeamId?: number\n teamId?: number\n competitionId?: number\n season?: string\n subject?: string\n personaHint?: string\n sport?: string\n}\n\n/** The page the widget sits on. Sent on greeting requests only, so the greeting can lead with that page. */\nexport interface PageContext {\n sport: 'football' | 'nba'\n kind?: 'section' | 'competition' | 'match'\n matchId?: string | number\n competitionId?: string | number\n}\n\n/** Onboarding presets stage 2 (contract §3): what a tool's Send asked for. Sent only from a tool's\n * Send, beside the full sentence in `message`. The server ignores it unless every value is valid. */\nexport interface ChatPreset {\n kind: 'max_price' | 'min_price' | 'combo' | 'market'\n /** max_price, min_price */\n price?: number\n /** max_price, min_price */\n count?: number\n /** combo */\n total?: number\n /** combo */\n legs?: number\n /** market */\n marketDeveloperName?: string\n /** The picks or legs the tool showed, in the order shown (R12: the answer reprices exactly these). */\n matchOddsIds: number[]\n /** The same picks' matchId, index for index with matchOddsIds (from the grid). */\n matchIds: number[]\n}\n\nexport interface ChatInput {\n message: string\n conversationId?: string\n actionId?: string\n /** Opaque predefined-action-contract ref (e.g. a club-dashboard tap). Authoritative over `message` when present. */\n actionRef?: string\n userContext?: UserContext\n grounding?: ChatGrounding\n /** Features this client can draw (e.g. \"price_presets\"). The server sends nothing that needs a\n * feature the list does not name; an absent list means today's responses. */\n clientCapabilities?: string[]\n /** The sport the visitor last chose on the greeting's sport switch (a server sport key such as \"nba\"); a hint for the default sport. */\n rememberedSport?: string\n /** Onboarding presets stage 2: set only by a preset tool's Send (contract §3). */\n preset?: ChatPreset\n page?: PageContext\n}\n\nexport type SignalType =\n | 'MatchPageView' | 'PlayerPageView' | 'TeamPageView' | 'MarketView'\n | 'SearchQuery' | 'SessionDepth' | 'TimeOnPage' | 'InsightViewed'\n | 'InsightMarketClicked' | 'BetPlacedFromInsight' | 'InsightScrollDepth'\n | 'ToolCall' | 'EntityMention' | 'Handoff' | 'FollowUpQuery' | 'RecommendationDismissed'\n\nexport type SignalEntityType =\n | 'Match' | 'Team' | 'Player' | 'Competition' | 'Market'\n | 'Article' | 'Session' | 'Query' | 'Conversation'\n\nexport interface SignalInput {\n signalType: SignalType\n entityType: SignalEntityType\n /** Either this or entityId is required -- an operator's UI mostly knows a display name. */\n entityName?: string\n /** Either this or entityName is required -- a dashboard tile knows its entity by id. */\n entityId?: string\n operatorUserId?: string\n anonymousUserId?: string\n /** Greeting dashboard layout this signal came from, when it is a dashboard tap. */\n dashboardLayout?: string\n /** Zero-based tile position within the dashboard, when it is a dashboard tap. */\n tileIndex?: number\n /** Wire sport key ('nba'); absent means football. Set by the widget, never by an operator. */\n sport?: string\n}\n\nexport type { SlipSport }\n\nexport interface SlipSelection {\n matchOddsId: number\n matchId: number\n oddsDecimal: number\n quotedAtUtc?: string\n insightId?: string\n conversationId?: string\n sport?: SlipSport\n}\n\nexport type AddToSlipRejectReason =\n | 'suspended' | 'closed' | 'login_required'\n | 'not_found' | 'limit' | 'unsupported'\n\nexport type AddToSlipResult =\n | { status: 'added'; slip?: { selectionCount: number; totalOddsDecimal?: number } }\n | { status: 'duplicate' }\n | { status: 'price_changed'; newOddsDecimal: number; accepted: boolean }\n | { status: 'rejected'; reason: AddToSlipRejectReason; message?: string }\n\nexport type AddToSlipHandler = (\n selection: SlipSelection,\n) => Promise<AddToSlipResult | void> | AddToSlipResult | void\n\nconst REJECT_REASONS = ['suspended', 'closed', 'login_required', 'not_found', 'limit', 'unsupported']\n\nexport function isAddToSlipResult(v: unknown): v is AddToSlipResult {\n if (typeof v !== 'object' || v === null) return false\n const o = v as Record<string, unknown>\n switch (o.status) {\n case 'added':\n case 'duplicate':\n return true\n case 'price_changed':\n return typeof o.newOddsDecimal === 'number'\n && Number.isFinite(o.newOddsDecimal)\n && typeof o.accepted === 'boolean'\n case 'rejected':\n return typeof o.reason === 'string'\n && REJECT_REASONS.includes(o.reason)\n default:\n return false\n }\n}\n","export interface SportSpec { readonly slipPrefix: string; readonly monitorPrefix: string; readonly label: string; readonly slippable: boolean; readonly wireKey: string | undefined }\n\nexport const SPORTS = {\n basketball: { slipPrefix: 'bb:', monitorPrefix: 'nba:', label: 'NBA', slippable: true, wireKey: 'nba' },\n americanfootball: { slipPrefix: 'af:', monitorPrefix: 'nfl:', label: 'NFL', slippable: true, wireKey: 'nfl' },\n} as const satisfies Record<string, SportSpec>\n\nexport type NonFootballSport = keyof typeof SPORTS\n/** The sport keys the server accepts on a signal or widget event: only a sport with a wireKey. */\nexport type WireSport = NonNullable<(typeof SPORTS)[NonFootballSport]['wireKey']>\nexport type QualifiedType = 'game' | 'team' | 'player' | 'competition' | 'market'\n/** The sports whose prices can reach an operator slip or a pin: those the map marks slippable. */\nexport type SlipSport = { [K in NonFootballSport]: (typeof SPORTS)[K]['slippable'] extends true ? K : never }[NonFootballSport]\n\n/** undefined means football: every sport the map does not know is football. */\nexport function sportOf(v: unknown): NonFootballSport | undefined {\n return typeof v === 'string' && Object.prototype.hasOwnProperty.call(SPORTS, v) ? (v as NonFootballSport) : undefined\n}\n\n/** True for football (no sport) and for a sport the map marks slippable: the only cases that may pin or slip. */\nexport function mayPinOrSlip(v: unknown): boolean {\n const sport = sportOf(v)\n return sport === undefined || SPORTS[sport].slippable\n}\n\n/** The sport when it may take a slip pick or a pin; undefined for football and for a sport that never does. */\nexport function slipSportOf(v: unknown): SlipSport | undefined {\n const sport = sportOf(v)\n return sport !== undefined && SPORTS[sport].slippable ? (sport as SlipSport) : undefined\n}\n\n/** The key the server reads as `sport`; undefined for football and for a sport without a wireKey. */\nexport function toWireSport(v: unknown): WireSport | undefined {\n const sport = sportOf(v)\n return sport === undefined ? undefined : (SPORTS[sport].wireKey as WireSport | undefined)\n}\n\n/** A server sport key (a set's `sport`) back to the key the server reads on a signal; undefined unless the map carries it as a wireKey. */\nexport function fromWireSport(v: unknown): WireSport | undefined {\n return typeof v === 'string' && Object.values(SPORTS).some((s) => s.wireKey === v) ? (v as WireSport) : undefined\n}\n\nexport function qualifiedId(sport: unknown, type: QualifiedType, id: string): string {\n const wire = toWireSport(sport)\n return wire ? `${wire}:${type}:${id}` : id\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/eventLog.ts","../src/client.ts","../src/matchKey.ts","../src/types.ts","../src/sports.ts"],"sourcesContent":["export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\n// B4 Q7: the codes a brand's limit refuses with. Any other 429 stays a plain RateLimitError.\nexport const LIMIT_CODES = ['daily_cap', 'quota_exhausted', 'assistant_paused'] as const\nexport type LimitCode = (typeof LIMIT_CODES)[number]\nexport function isLimitCode(code: unknown): code is LimitCode {\n return typeof code === 'string' && (LIMIT_CODES as readonly string[]).includes(code)\n}\nexport interface LimitDetails {\n limitCode: LimitCode\n resetsAt?: string\n /** The brand's or the built-in text, already in the user's language. */\n message?: string\n}\nexport class LimitError extends RateLimitError {\n readonly limitCode: LimitCode\n readonly resetsAt?: string\n readonly limitMessage?: string\n constructor(details: LimitDetails, retryAfter?: number) {\n super(retryAfter, details.message ?? 'Limit reached')\n this.limitCode = details.limitCode\n this.resetsAt = details.resetsAt\n this.limitMessage = details.message\n }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, isLimitCode, LimitError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type {\n BuilderGridPayload, BuilderGridRequest, ClubFanDashboardPayload, ClubFixturesPayload, ClubSquadPayload, ClubSquadStatsPayload, ClubPlayerDetailPayload, ClubRecordsPayload, ClubStandingsPayload, GameListPayload, GameResultPayload, GameStatePayload, LeaderboardPayload,\n FavouriteEntity, FavouriteKind, FavouritesNoIdentity, FavouritesPayload, FavouriteStarResponse, LeagueStarResult, LiveMonitorSnapshot, MarketOddsBlock, PinRef, PlayerPropsBundle, PresetGrid, PresetGridOptions, SchedulePayload, StatesPayload, SubmitPlayBody, SubmitPlayResult,\n} from './events'\nimport type { SlipSport } from './sports'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n client?: string\n}\n\nexport function headersFor(cfg: ResolvedConfig, json: boolean): Record<string, string> {\n const h: Record<string, string> = json ? { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey } : { 'X-SS-Public-Key': cfg.publicKey }\n if (cfg.client) h['X-SS-Client'] = cfg.client\n return h\n}\n\nconst OPERATOR_USER_ID_HEADER = 'X-SS-Operator-User-Id'\nconst ANONYMOUS_USER_ID_HEADER = 'X-SS-Anonymous-User-Id'\n\n// Same rule as the gateway's VisitorIdHeaders.IsValid: printable ASCII, 1 to 128 characters.\nconst SENDABLE_ID = /^[\\x20-\\x7E]{1,128}$/\n\n// Visitor ids travel in these two headers on every gateway call, never in the query string or the JSON\n// body. The trimmed id is sent (fetch strips edge whitespace anyway). An id that is blank or that the\n// gateway would reject is left out like a blank one, so a bad id can never make fetch throw.\nexport function isSendableId(id?: string): boolean {\n const v = id?.trim()\n return !!v && SENDABLE_ID.test(v)\n}\n\nexport function identityHeaders(operatorUserId?: string, anonymousUserId?: string): Record<string, string> {\n const h: Record<string, string> = {}\n if (isSendableId(operatorUserId)) h[OPERATOR_USER_ID_HEADER] = operatorUserId!.trim()\n if (isSendableId(anonymousUserId)) h[ANONYMOUS_USER_ID_HEADER] = anonymousUserId!.trim()\n return h\n}\n\ninterface BodyIds { operatorUserId?: string; anonymousUserId?: string }\n\nfunction splitIdentity(body: object): { identity: Record<string, string>; rest: Record<string, unknown> } {\n const { operatorUserId, anonymousUserId, ...rest } = body as BodyIds & Record<string, unknown>\n return { identity: identityHeaders(operatorUserId, anonymousUserId), rest }\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\n// B4 Q7: a limit refusal is a 429 whose problem+json body names the limit. The gateway's own per-minute 429 sets\n// Retry-After without exposing it to browsers, so a missing header is normal: the body's retryAfterSeconds covers\n// it, and no countdown is shown when neither is present.\nexport async function chatError(res: Response): Promise<WidgetSdkError> {\n const base = toWidgetError(res.status, res.headers.get('Retry-After'))\n if (!(base instanceof RateLimitError)) return base\n let body: unknown\n try { body = await res.json() } catch { return base }\n if (typeof body !== 'object' || body === null) return base\n const b = body as Record<string, unknown>\n if (!isLimitCode(b.errorCode)) return base\n const text = (v: unknown): string | undefined => (typeof v === 'string' && v.trim() !== '' ? v : undefined)\n const header = res.headers.get('Retry-After')?.trim()\n const headerRetry = header != null && /^\\d+$/.test(header) ? Number(header) : undefined\n const bodyRetry = typeof b.retryAfterSeconds === 'number' && Number.isFinite(b.retryAfterSeconds) && b.retryAfterSeconds >= 0 ? b.retryAfterSeconds : undefined\n return new LimitError(\n { limitCode: b.errorCode, resetsAt: text(b.resetsAt), message: text(b.message) },\n headerRetry ?? bodyRetry,\n )\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(\n cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal, identity: Record<string, string> = {},\n): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const { userContext, ...rest } = input\n let body: object = rest\n let identity: Record<string, string> = {}\n if (userContext) {\n const split = splitIdentity(userContext)\n identity = split.identity\n body = Object.keys(split.rest).length > 0 ? { ...rest, userContext: split.rest } : rest\n }\n const res = await send(cfg, 'chat', body, signal, identity)\n if (!res.ok || res.body == null) throw await chatError(res)\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const { identity, rest } = splitIdentity(wireBody)\n const res = await send(cfg, 'signals', rest, signal, identity)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n\nexport async function postEvents(cfg: ResolvedConfig, batch: object): Promise<void> {\n const { identity, rest } = splitIdentity(batch)\n const res = await send(cfg, 'events', rest, undefined, identity)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n\n// Best-effort tail flush on page hide/unload. Uses fetch keepalive (not sendBeacon) because the\n// gateway requires the X-SS-Public-Key header, which sendBeacon cannot set. Both the synchronous\n// call and the returned promise are guarded -- an async rejection (real network failure, or\n// Chrome's ~64KB keepalive body cap) must never surface as an unhandled rejection, since this\n// runs inside an operator-embedded widget during page-hide and would show up as noise in the\n// OPERATOR's own error monitoring.\nexport function postEventsKeepalive(cfg: ResolvedConfig, batch: object): void {\n try {\n const { identity, rest } = splitIdentity(batch)\n void cfg.fetch(endpoint(cfg, 'events'), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(rest),\n keepalive: true,\n }).catch(() => { /* best-effort tail flush -- swallow async rejection too */ })\n } catch {\n /* best-effort tail flush -- never throw on unload */\n }\n}\n\nexport async function getLiveDashboard(cfg: ResolvedConfig): Promise<ClubFanDashboardPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-dashboard'), { method: 'GET', headers: headersFor(cfg, false) })\n // 204 is the definitive \"not live / match over\" signal -- the poll loop stops on it.\n // Any other non-ok status (e.g. a transient 502/503/504) must throw rather than return\n // null, so the poll loop's per-tick try/catch retries on the next tick instead of stopping.\n if (res.status === 204) return null\n if (!res.ok) throw new Error(`live-dashboard ${res.status}`)\n return (await res.json()) as ClubFanDashboardPayload\n}\n\n// 404 is the definitive \"live monitor disabled for this operator\" signal -- the poll loop\n// stops and the tabs disable. Any other non-ok status must throw so the per-tick\n// try/catch retries next tick instead of silently disabling the feature.\nexport async function postLiveMonitor(cfg: ResolvedConfig, pins: PinRef[], locale?: string): Promise<LiveMonitorSnapshot | null> {\n const body: { pins: PinRef[]; locale?: string } = { pins }\n if (locale) body.locale = locale\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(body),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor ${res.status}`)\n return (await res.json()) as LiveMonitorSnapshot\n}\n\nexport async function postMarketOdds(\n cfg: ResolvedConfig, matchId: number, marketDeveloperName: string, sport?: SlipSport,\n): Promise<MarketOddsBlock | null> {\n const body: { matchId: number; marketDeveloperName: string; sport?: SlipSport } = { matchId, marketDeveloperName }\n if (sport) body.sport = sport\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/market'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(body),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/market ${res.status}`)\n return (await res.json()) as MarketOddsBlock\n}\n\nexport async function postPlayerProps(cfg: ResolvedConfig, matchId: number, sport?: 'americanfootball'): Promise<PlayerPropsBundle | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/props'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify(sport ? { matchId, sport } : { matchId }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/props ${res.status}`)\n return (await res.json()) as PlayerPropsBundle\n}\n\n// 404 mirrors postLiveMonitor: the definitive \"live monitor disabled for this operator\" signal.\n// Every other non-ok status throws so the caller's per-tick catch retries next tick.\nexport async function postSchedule(\n cfg: ResolvedConfig, localDate: string, utcOffsetMinutes: number,\n operatorUserId?: string, anonymousUserId?: string,\n): Promise<SchedulePayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/schedule'), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identityHeaders(operatorUserId, anonymousUserId) },\n body: JSON.stringify({ localDate, utcOffsetMinutes, sports: ['basketball', 'americanfootball'] }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/schedule ${res.status}`)\n return (await res.json()) as SchedulePayload\n}\n\nexport async function postLeagueStar(\n cfg: ResolvedConfig, competitionId: number, starred: boolean,\n operatorUserId?: string, anonymousUserId?: string,\n): Promise<LeagueStarResult | null> {\n const res = await cfg.fetch(endpoint(cfg, `leagues/${competitionId}/star`), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identityHeaders(operatorUserId, anonymousUserId) },\n body: JSON.stringify({ starred }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`leagues/star ${res.status}`)\n return (await res.json()) as LeagueStarResult\n}\n\nexport async function postStates(\n cfg: ResolvedConfig, matchIds: number[], nbaGameIds?: number[], nflGameIds?: number[],\n): Promise<StatesPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'live-monitor/states'), {\n method: 'POST',\n headers: headersFor(cfg, true),\n body: JSON.stringify({\n matchIds,\n ...(nbaGameIds?.length ? { nbaGameIds } : {}),\n ...(nflGameIds?.length ? { nflGameIds } : {}),\n }),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`live-monitor/states ${res.status}`)\n return (await res.json()) as StatesPayload\n}\n\nfunction q(parts: Record<string, string | number | undefined>): string {\n const kept = Object.entries(parts)\n .filter(([, v]) => v !== undefined && v !== '')\n .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)\n return kept.length ? `?${kept.join('&')}` : ''\n}\n\nexport async function getGames(cfg: ResolvedConfig, operatorUserId?: string, gameDay?: string): Promise<GameListPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'games' + q({ gameDay })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`games ${res.status}`)\n return (await res.json()) as GameListPayload\n}\n\nexport async function getGameConfig(cfg: ResolvedConfig, gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameStatePayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}` + q({ fixtureId, gameDay, locale })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`game-config ${res.status}`)\n return (await res.json()) as GameStatePayload\n}\n\nexport async function getGameResult(cfg: ResolvedConfig, gameId: string, operatorUserId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameResultPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}/result` + q({ fixtureId, gameDay, locale })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`game-result ${res.status}`)\n return (await res.json()) as GameResultPayload\n}\n\nexport async function postPlay(cfg: ResolvedConfig, gameId: string, body: SubmitPlayBody, locale?: string): Promise<SubmitPlayResult | null> {\n const { identity, rest } = splitIdentity(body)\n const res = await cfg.fetch(endpoint(cfg, `games/${encodeURIComponent(gameId)}/plays` + q({ locale })), {\n method: 'POST',\n headers: { ...headersFor(cfg, true), ...identity },\n body: JSON.stringify(rest),\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`play ${res.status}`)\n return (await res.json()) as SubmitPlayResult\n}\n\nexport async function getLeaderboard(cfg: ResolvedConfig, operatorUserId?: string, week?: string): Promise<LeaderboardPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'games/leaderboard' + q({ week })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`leaderboard ${res.status}`)\n return (await res.json()) as LeaderboardPayload\n}\n\nexport async function getClubFixtures(cfg: ResolvedConfig, competitionId?: number, limit?: number): Promise<ClubFixturesPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/fixtures' + q({ competitionId, limit })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-fixtures ${res.status}`)\n return (await res.json()) as ClubFixturesPayload\n}\n\nexport async function getClubStandings(cfg: ResolvedConfig, competitionId?: number): Promise<ClubStandingsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/standings' + q({ competitionId })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-standings ${res.status}`)\n return (await res.json()) as ClubStandingsPayload\n}\n\nexport async function getClubSquad(cfg: ResolvedConfig): Promise<ClubSquadPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/squad'), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-squad ${res.status}`)\n return (await res.json()) as ClubSquadPayload\n}\n\nexport async function getClubSquadStats(cfg: ResolvedConfig): Promise<ClubSquadStatsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/squad/stats'), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-squad-stats ${res.status}`)\n return (await res.json()) as ClubSquadStatsPayload\n}\n\nexport async function getClubPlayerDetail(cfg: ResolvedConfig, playerId: number): Promise<ClubPlayerDetailPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, `club/player/${encodeURIComponent(String(playerId))}`), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-player ${res.status}`)\n return (await res.json()) as ClubPlayerDetailPayload\n}\n\nexport async function getClubRecords(cfg: ResolvedConfig, limit?: number): Promise<ClubRecordsPayload | null> {\n const res = await cfg.fetch(endpoint(cfg, 'club/records' + q({ limit })), { method: 'GET', headers: headersFor(cfg, false) })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`club-records ${res.status}`)\n return (await res.json()) as ClubRecordsPayload\n}\n\n// Onboarding presets stage 2 (contract §1). 404 is the definitive \"no presets for this visitor\"\n// answer (flag off, not a betting operator, or cool-off). 503 and every other non-ok status throw:\n// the widget keeps any grid it already has and asks again on the next panel open.\n// operatorUserId is optional, sent as the games routes send it (in its header): the cool-off check (D3)\n// needs it, and a request without it is an anonymous visitor.\nexport async function getPricePresets(\n cfg: ResolvedConfig, locale: string, operatorUserId?: string, options?: PresetGridOptions,\n): Promise<PresetGrid | null> {\n const res = await cfg.fetch(endpoint(cfg, 'price-presets' + q({ locale, pool: options?.pool })), { method: 'GET', headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId) } })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`price-presets ${res.status}`)\n return (await res.json()) as PresetGrid\n}\n\n// 404 is the cool-off / non-betting-operator answer, as getPricePresets. Identity travels in headers only, never the query.\nexport async function getBuilderGrid(\n cfg: ResolvedConfig, locale: string, req: BuilderGridRequest,\n): Promise<BuilderGridPayload | null> {\n const query = q({\n locale,\n sport: req.sport,\n legs: req.legs,\n total: req.total,\n marketKey: req.marketKey ?? undefined,\n matchIds: req.widen ? undefined : req.matchIds.join(','),\n widen: req.widen ? 'true' : undefined,\n allLegs: req.allLegs ? 'true' : undefined,\n })\n const res = await cfg.fetch(endpoint(cfg, 'price-presets' + query), {\n method: 'GET',\n headers: { ...headersFor(cfg, false), ...identityHeaders(req.operatorUserId, req.anonymousUserId) },\n })\n if (res.status === 404) return null\n if (!res.ok) throw new Error(`price-presets ${res.status}`)\n return (await res.json()) as BuilderGridPayload\n}\n\n// Favourites routes carry identity in headers only and send no body. A non-ok answer, including the\n// gateway's 429 TooManyVisitorIds, resolves the call's failure value; only a transport failure throws.\nfunction favouritePath(kind: FavouriteKind, id: string): string {\n return `favourites/${encodeURIComponent(kind)}/${encodeURIComponent(id)}`\n}\n\nfunction favouritesFetch(\n cfg: ResolvedConfig, method: 'GET' | 'PUT' | 'POST' | 'DELETE', path: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<Response> {\n return cfg.fetch(endpoint(cfg, path), { method, headers: { ...headersFor(cfg, false), ...identityHeaders(operatorUserId, anonymousUserId) } })\n}\n\nexport async function getFavourites(\n cfg: ResolvedConfig, sport: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouritesPayload | FavouritesNoIdentity | null> {\n const res = await favouritesFetch(cfg, 'GET', 'favourites' + q({ sport }), operatorUserId, anonymousUserId)\n if (res.status === 400) {\n const body = (await res.json().catch(() => null)) as { code?: string } | null\n return body?.code === 'NoAcceptedIdentity' ? 'noAcceptedIdentity' : null\n }\n if (!res.ok) return null\n return (await res.json()) as FavouritesPayload\n}\n\nconst MIN_FAVOURITES_QUERY = 2\n\nexport async function searchFavourites(\n cfg: ResolvedConfig, sport: string, query: string, kind: FavouriteKind, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouriteEntity[] | null> {\n const text = query.trim()\n if (text.length < MIN_FAVOURITES_QUERY) return []\n const res = await favouritesFetch(cfg, 'GET', 'favourites/search' + q({ sport, q: text, kind }), operatorUserId, anonymousUserId)\n if (!res.ok) return null\n return ((await res.json()) as { results: FavouriteEntity[] }).results\n}\n\n// A 409 whose body says atCap is an answer, not a failure: it carries the count and cap.\nexport async function putFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<FavouriteStarResponse | null> {\n const res = await favouritesFetch(cfg, 'PUT', favouritePath(kind, id), operatorUserId, anonymousUserId)\n if (res.ok) return (await res.json()) as FavouriteStarResponse\n if (res.status !== 409) return null\n const body = (await res.json().catch(() => null)) as { status?: string; count?: number; cap?: number } | null\n return body?.status === 'atCap' ? { status: 'atCap', count: body.count, cap: body.cap } : null\n}\n\nexport async function deleteFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'DELETE', favouritePath(kind, id), operatorUserId, anonymousUserId)).ok\n}\n\nexport async function clearFavourites(\n cfg: ResolvedConfig, sport: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'DELETE', 'favourites' + q({ sport }), operatorUserId, anonymousUserId)).ok\n}\n\n// 404 NotLearned and 409 Starred are not ok, so both resolve false.\nexport async function hideFavourite(\n cfg: ResolvedConfig, kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string,\n): Promise<boolean> {\n return (await favouritesFetch(cfg, 'POST', `${favouritePath(kind, id)}/hide`, operatorUserId, anonymousUserId)).ok\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { NetworkError, WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n let chunk: ReadableStreamReadResult<Uint8Array>\n try {\n chunk = await reader.read()\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n const { done, value } = chunk\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName?: string; entityId?: string\n operatorUserId?: string; anonymousUserId?: string; dashboardLayout?: string; tileIndex?: number\n sport?: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return {\n signalType, entityType, entityName: input.entityName, entityId: input.entityId,\n operatorUserId: input.operatorUserId, anonymousUserId: input.anonymousUserId,\n dashboardLayout: input.dashboardLayout, tileIndex: input.tileIndex, sport: input.sport,\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport type {\n BuilderGridPayload, BuilderGridRequest, ClubFanDashboardPayload, ClubFixturesPayload, ClubSquadPayload, ClubSquadStatsPayload, ClubPlayerDetailPayload, ClubRecordsPayload, ClubStandingsPayload, GameListPayload, GameResultPayload, GameStatePayload, LeaderboardPayload,\n FavouriteEntity, FavouriteKind, FavouritesNoIdentity, FavouritesPayload, FavouriteStarResponse, LeagueStarResult, LiveMonitorSnapshot, MarketOddsBlock, PinRef, PlayerPropsBundle, PresetGrid, PresetGridOptions, SchedulePayload, StatesPayload, SubmitPlayResult,\n} from './events'\nimport {\n clearFavourites, deleteFavourite, getFavourites, hideFavourite, putFavourite, searchFavourites,\n getClubFixtures, getClubPlayerDetail, getClubRecords, getClubSquad, getClubSquadStats, getClubStandings, getGameConfig, getGameResult, getGames, getLeaderboard, getLiveDashboard, getBuilderGrid, getPricePresets,\n postLeagueStar, postLiveMonitor, postMarketOdds, postPlayerProps, postPlay, postSchedule, postSignal, postStates, type ResolvedConfig,\n isSendableId,\n} from './http'\nimport { toSignalWireBody } from './signals'\nimport type { SlipSport } from './sports'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: SignalInput): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n const anonymousUserId = isSendableId(operatorUserId) ? undefined : (input.anonymousUserId ?? this.context?.anonymousUserId)\n if (!operatorUserId && !anonymousUserId) {\n throw new Error('operatorUserId or anonymousUserId is required (set it on conversation() or pass it to sendSignal)')\n }\n if (!input.entityId && !input.entityName) {\n throw new Error('entityId or entityName is required')\n }\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId, anonymousUserId }))\n }\n\n getLiveDashboard(): Promise<ClubFanDashboardPayload | null> {\n return getLiveDashboard(this.cfg)\n }\n\n getLiveMonitor(pins: PinRef[], locale?: string): Promise<LiveMonitorSnapshot | null> {\n return postLiveMonitor(this.cfg, pins, locale)\n }\n\n getMarketOdds(matchId: number, marketDeveloperName: string, sport?: SlipSport): Promise<MarketOddsBlock | null> {\n return postMarketOdds(this.cfg, matchId, marketDeveloperName, sport)\n }\n\n getPlayerProps(matchId: number, sport?: 'americanfootball'): Promise<PlayerPropsBundle | null> {\n return postPlayerProps(this.cfg, matchId, sport)\n }\n\n getPricePresets(locale: string, options?: PresetGridOptions): Promise<PresetGrid | null> {\n return getPricePresets(this.cfg, locale, this.context?.operatorUserId, options)\n }\n\n getBuilderGrid(locale: string, req: BuilderGridRequest): Promise<BuilderGridPayload | null> {\n return getBuilderGrid(this.cfg, locale, req)\n }\n\n getSchedule(\n localDate: string, utcOffsetMinutes: number, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<SchedulePayload | null> {\n return postSchedule(this.cfg, localDate, utcOffsetMinutes, operatorUserId, anonymousUserId)\n }\n\n starLeague(\n competitionId: number, starred: boolean, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<LeagueStarResult | null> {\n return postLeagueStar(this.cfg, competitionId, starred, operatorUserId, anonymousUserId)\n }\n\n getFavourites(sport: string, operatorUserId?: string, anonymousUserId?: string): Promise<FavouritesPayload | FavouritesNoIdentity | null> {\n return getFavourites(this.cfg, sport, operatorUserId, anonymousUserId)\n }\n\n searchFavourites(\n sport: string, query: string, kind: FavouriteKind, operatorUserId?: string, anonymousUserId?: string,\n ): Promise<FavouriteEntity[] | null> {\n return searchFavourites(this.cfg, sport, query, kind, operatorUserId, anonymousUserId)\n }\n\n putFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<FavouriteStarResponse | null> {\n return putFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n deleteFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return deleteFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n clearFavourites(sport: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return clearFavourites(this.cfg, sport, operatorUserId, anonymousUserId)\n }\n\n hideFavourite(kind: FavouriteKind, id: string, operatorUserId?: string, anonymousUserId?: string): Promise<boolean> {\n return hideFavourite(this.cfg, kind, id, operatorUserId, anonymousUserId)\n }\n\n getStates(matchIds: number[], nbaGameIds?: number[], nflGameIds?: number[]): Promise<StatesPayload | null> {\n return postStates(this.cfg, matchIds, nbaGameIds, nflGameIds)\n }\n\n getGames(gameDay?: string): Promise<GameListPayload | null> {\n return getGames(this.cfg, this.context?.operatorUserId, gameDay)\n }\n\n getGameConfig(gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameStatePayload | null> {\n return getGameConfig(this.cfg, gameId, fixtureId, gameDay, locale)\n }\n\n getGameResult(gameId: string, fixtureId?: number, gameDay?: string, locale?: string): Promise<GameResultPayload | null> {\n const operatorUserId = this.context?.operatorUserId\n if (!operatorUserId) return Promise.resolve(null)\n return getGameResult(this.cfg, gameId, operatorUserId, fixtureId, gameDay, locale)\n }\n\n postPlay(gameId: string, answerJson: string, gameDay: string, fixtureId?: number, locale?: string): Promise<SubmitPlayResult | null> {\n const operatorUserId = this.context?.operatorUserId\n if (!operatorUserId) return Promise.resolve(null)\n return postPlay(this.cfg, gameId, { operatorUserId, gameDay, answerJson, fixtureId }, locale)\n }\n\n getLeaderboard(week?: string): Promise<LeaderboardPayload | null> {\n return getLeaderboard(this.cfg, this.context?.operatorUserId, week)\n }\n\n getClubFixtures(competitionId?: number, limit?: number): Promise<ClubFixturesPayload | null> {\n return getClubFixtures(this.cfg, competitionId, limit)\n }\n getClubStandings(competitionId?: number): Promise<ClubStandingsPayload | null> {\n return getClubStandings(this.cfg, competitionId)\n }\n getClubSquad(): Promise<ClubSquadPayload | null> {\n return getClubSquad(this.cfg)\n }\n getClubSquadStats(): Promise<ClubSquadStatsPayload | null> {\n return getClubSquadStats(this.cfg)\n }\n getClubPlayerDetail(playerId: number): Promise<ClubPlayerDetailPayload | null> {\n return getClubPlayerDetail(this.cfg, playerId)\n }\n getClubRecords(limit?: number): Promise<ClubRecordsPayload | null> {\n return getClubRecords(this.cfg, limit)\n }\n}\n","export type WidgetEntityEventName =\n | 'pin_add' | 'pin_remove' | 'slip_click' | 'slip_result'\n | 'tile_tap'\n | 'slip_remove' | 'bet_placed' | 'match_view' | 'match_open' | 'combo_add'\n\nexport type WidgetPopupEventName = 'popup_shown' | 'popup_opened' | 'popup_dismissed'\n\nexport type WidgetPopupAskEventName = 'popup_ask_tap'\n\nexport type WidgetOpenEventName = 'widget_open'\n\nexport type WidgetSportSwitchEventName = 'dashboard_sport_switch'\n\nexport type WidgetEventName =\n WidgetEntityEventName | WidgetPopupEventName | WidgetPopupAskEventName | WidgetOpenEventName | WidgetSportSwitchEventName\n\nexport type WidgetEntityType = 'match' | 'team' | 'player' | 'competition' | 'market'\n\n/** `totalChosen` is the visitor's total control as a string on the wire; `totalActual` is the server's total for the shown combo. */\nexport interface ComboAddMetadata {\n sport: string\n legs: number\n totalChosen: 'any' | '3' | '5' | '10' | '20' | '50'\n totalActual: number\n markets: string[]\n}\n\nexport interface WidgetEventInput {\n name: WidgetEntityEventName\n entityType: WidgetEntityType\n entityId?: string\n entityName?: string\n marketDeveloperName?: string\n outcome?: string\n /** Football match id of the slip selection (slip_click / slip_result). */\n matchId?: number\n /** The raw odds label as stored (\"Home\", \"Over\", \"Home/Draw\"), never a joined display string. Max 64. */\n selection?: string\n /** The raw line (\"2.5\"). Max 32; omit when empty. */\n line?: string\n /** Decimal price shown when the selection was added. */\n odds?: number\n /** Wire sport key ('nba'); absent means football. */\n sport?: string\n /** combo_add only: what the visitor asked for and what the server returned. */\n metadata?: ComboAddMetadata\n}\n\n/** Launcher popup telemetry: counted server-side, never tied to an entity. */\nexport type WidgetPopupEventInput =\n { name: WidgetPopupEventName } & { [K in Exclude<keyof WidgetEventInput, 'name'>]?: never }\n\n/** A tap on one of the launcher bubble's asks. `outcome` carries the ask's position, \"0\" or \"1\"\n * (contract §5): the gateway forwards only the fields of its own event model, and outcome is its\n * one free-text field. */\nexport type WidgetPopupAskEventInput =\n { name: WidgetPopupAskEventName; outcome: string } & { [K in Exclude<keyof WidgetEventInput, 'name' | 'outcome'>]?: never }\n\n/** The panel opening: entity-free, each open is added to the user's count for the day. */\nexport type WidgetOpenEventInput =\n { name: WidgetOpenEventName } & { [K in Exclude<keyof WidgetEventInput, 'name'>]?: never }\n\n/** The greeting sport switch: `outcome` is the sport switched to (a server sport key). Entity-free; the server drops an unknown outcome. */\nexport type WidgetSportSwitchEventInput =\n { name: WidgetSportSwitchEventName; outcome: string } & { [K in Exclude<keyof WidgetEventInput, 'name' | 'outcome'>]?: never }\n\nexport type WidgetLogInput =\n WidgetEventInput | WidgetPopupEventInput | WidgetPopupAskEventInput | WidgetOpenEventInput | WidgetSportSwitchEventInput\n\nexport type WireEvent = WidgetLogInput & {\n seq: number\n at: number\n}\n\nexport interface EventBatch {\n v: 1\n sessionId: string\n conversationId?: string\n operatorUserId?: string\n anonymousUserId?: string\n /**\n * Events dropped after exhausting delivery attempts during a PRIOR flush cycle — not a count of\n * this batch's own events. Rides whichever batch is built next after the drop, then is omitted\n * (0/undefined) once a clean cycle passes without a new failure.\n */\n dropped?: number\n /**\n * Failed delivery attempts from a PRIOR flush cycle — not retries of this batch's own events.\n * Rides whichever batch is built next after the failure, then is omitted (0/undefined) once a\n * clean cycle passes without a new failure.\n */\n retries?: number\n events: WireEvent[]\n}\n\nexport interface EventLoggerOptions {\n /** Normal delivery (fetch). Rejecting triggers the retry/backoff loop. */\n flush: (batch: EventBatch) => Promise<void>\n /** Best-effort tail flush on page hide/unload (fetch keepalive). Never awaited. */\n flushKeepalive: (batch: EventBatch) => void\n /** Injectable clock (tests). Defaults to Date.now. */\n now?: () => number\n batchIntervalMs?: number\n maxBatch?: number\n maxAttempts?: number\n}\n\nexport interface EventLogger {\n log(input: WidgetLogInput): void\n setIdentity(id: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): void\n flushNow(): Promise<void>\n flushOnHide(): void\n dispose(): void\n /** Undoes dispose(). React StrictMode runs an effect's cleanup and then its setup again on the\n * same logger, so the widget's setup has to be able to bring a disposed logger back. */\n resume(): void\n}\n\nconst IMMEDIATE: ReadonlySet<WidgetEventName> = new Set([\n 'pin_add', 'pin_remove', 'slip_click', 'slip_result', 'slip_remove', 'bet_placed', 'combo_add',\n])\n\n// Queued without arming the batch timer: the event leaves with the next flush of any cause. A match\n// page view fires for every visitor, so it must never start a request of its own.\nconst DEFERRED: ReadonlySet<WidgetEventName> = new Set(['match_view'])\n\nconst DEFAULT_BATCH_INTERVAL_MS = 10_000\nconst DEFAULT_MAX_BATCH = 50\nconst DEFAULT_MAX_ATTEMPTS = 3\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction makeSessionId(): string {\n const c: Crypto | undefined = globalThis.crypto\n if (c && typeof c.randomUUID === 'function') return c.randomUUID()\n return `s_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`\n}\n\nclass EventLoggerImpl implements EventLogger {\n private readonly sessionId = makeSessionId()\n private readonly now: () => number\n private readonly batchIntervalMs: number\n private readonly maxBatch: number\n private readonly maxAttempts: number\n\n private queue: WireEvent[] = []\n private seq = 0\n private retries = 0\n private dropped = 0\n private identity: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string } = {}\n private timer: ReturnType<typeof setTimeout> | null = null\n private inFlight: Promise<void> | null = null\n private disposed = false\n\n constructor(private readonly opts: EventLoggerOptions) {\n this.now = opts.now ?? (() => Date.now())\n this.batchIntervalMs = opts.batchIntervalMs ?? DEFAULT_BATCH_INTERVAL_MS\n this.maxBatch = opts.maxBatch ?? DEFAULT_MAX_BATCH\n this.maxAttempts = opts.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n }\n\n log(input: WidgetLogInput): void {\n if (this.disposed) return\n const event: WireEvent = { ...input, seq: ++this.seq, at: this.now() }\n this.queue.push(event)\n if (IMMEDIATE.has(input.name)) {\n this.trigger()\n } else if (this.queue.length >= this.maxBatch) {\n this.trigger()\n } else if (!DEFERRED.has(input.name)) {\n this.armTimer()\n }\n }\n\n setIdentity(id: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): void {\n this.identity = { ...this.identity, ...id }\n }\n\n async flushNow(): Promise<void> {\n if (this.inFlight) await this.inFlight\n if (this.queue.length > 0) await this.doFlush()\n }\n\n flushOnHide(): void {\n this.clearTimer()\n const batch = this.buildBatch()\n if (batch === null) return\n this.opts.flushKeepalive(batch)\n }\n\n dispose(): void {\n this.disposed = true\n this.clearTimer()\n }\n\n resume(): void {\n this.disposed = false\n }\n\n private armTimer(): void {\n if (this.timer !== null) return\n this.timer = setTimeout(() => {\n this.timer = null\n this.trigger()\n }, this.batchIntervalMs)\n }\n\n private clearTimer(): void {\n if (this.timer === null) return\n clearTimeout(this.timer)\n this.timer = null\n }\n\n private trigger(): void {\n if (this.disposed) return\n if (this.inFlight) return\n this.inFlight = this.doFlush().finally(() => {\n this.inFlight = null\n // An immediate (or maxBatch-triggered) log() call that arrived while this flush was\n // in-flight was a no-op above -- drain it now instead of stranding it until some later\n // log()/flushNow()/dispose() call. Guarded by the disposed check at the top of trigger()\n // itself, so a straggler queued just before dispose() does not fire a flush after it.\n if (this.queue.length > 0) this.trigger()\n })\n }\n\n /**\n * Snapshots the queue + carry-over counters (see EventBatch.dropped/retries) into a batch and\n * resets both for the next cycle. Returns null only when there is truly nothing to report --\n * an empty queue AND no pending dropped/retries -- so a pending counter-only report (queue\n * drained by an exhausted flush, nothing logged since) still gets built and delivered.\n */\n private buildBatch(): EventBatch | null {\n if (this.queue.length === 0 && this.retries === 0 && this.dropped === 0) return null\n const events = this.queue\n this.queue = []\n const batch: EventBatch = { v: 1, sessionId: this.sessionId, ...this.identity, events }\n if (this.retries > 0) batch.retries = this.retries\n if (this.dropped > 0) batch.dropped = this.dropped\n this.retries = 0\n this.dropped = 0\n return batch\n }\n\n private async doFlush(): Promise<void> {\n this.clearTimer()\n const batch = this.buildBatch()\n if (batch === null) return\n for (let attempt = 1; attempt <= this.maxAttempts; attempt++) {\n try {\n await this.opts.flush(batch)\n return\n } catch {\n this.retries++\n if (attempt >= this.maxAttempts) {\n this.dropped += batch.events.length\n return\n }\n await delay(2 ** attempt * 50)\n }\n }\n }\n}\n\nexport function createEventLogger(opts: EventLoggerOptions): EventLogger {\n return new EventLoggerImpl(opts)\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { createEventLogger, type EventLogger } from './eventLog'\nimport { postEvents, postEventsKeepalive, postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n client: options.client,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n\n createEventLogger(identity?: { operatorUserId?: string; anonymousUserId?: string; conversationId?: string }): EventLogger {\n const logger = createEventLogger({\n flush: (batch) => postEvents(this.cfg, batch),\n flushKeepalive: (batch) => postEventsKeepalive(this.cfg, batch),\n })\n if (identity) logger.setIdentity(identity)\n return logger\n }\n}\n","export function matchKey(sport: string | undefined, id: number): string {\n return `${sport ?? 'football'}:${id}`\n}\n","import type { SlipSport } from './sports'\n\nexport type FetchLike = (input: string, init: RequestInit) => Promise<Response>\n\nexport interface StatsWidgetClientOptions {\n operatorId: string\n publicKey: string\n baseUrl?: string\n /** Advanced/testing: inject a fetch implementation. Defaults to globalThis.fetch. */\n fetch?: FetchLike\n /** Sent as X-SS-Client; set by widget-react. */\n client?: string\n}\n\nexport interface UserContext {\n operatorUserId?: string\n defaultLanguage?: string\n anonymousUserId?: string\n}\n\nexport interface ChatGrounding {\n kind?: string\n matchId?: number\n opponentTeamId?: number\n teamId?: number\n competitionId?: number\n season?: string\n subject?: string\n personaHint?: string\n sport?: string\n}\n\n/** The page the widget sits on. Sent on greeting requests only, so the greeting can lead with that page. */\nexport interface PageContext {\n sport: 'football' | 'nba'\n kind?: 'section' | 'competition' | 'match'\n matchId?: string | number\n competitionId?: string | number\n}\n\n/** Onboarding presets stage 2 (contract §3): what a tool's Send asked for. Sent only from a tool's\n * Send, beside the full sentence in `message`. The server ignores it unless every value is valid. */\nexport interface ChatPreset {\n kind: 'max_price' | 'min_price' | 'combo' | 'market'\n /** max_price, min_price */\n price?: number\n /** max_price, min_price */\n count?: number\n /** combo */\n total?: number\n /** combo */\n legs?: number\n /** market */\n marketDeveloperName?: string\n /** The picks or legs the tool showed, in the order shown (R12: the answer reprices exactly these). */\n matchOddsIds: number[]\n /** The same picks' matchId, index for index with matchOddsIds (from the grid). */\n matchIds: number[]\n}\n\nexport interface ChatInput {\n message: string\n conversationId?: string\n actionId?: string\n /** Opaque predefined-action-contract ref (e.g. a club-dashboard tap). Authoritative over `message` when present. */\n actionRef?: string\n userContext?: UserContext\n grounding?: ChatGrounding\n /** Features this client can draw (e.g. \"price_presets\"). The server sends nothing that needs a\n * feature the list does not name; an absent list means today's responses. */\n clientCapabilities?: string[]\n /** The sport the visitor last chose on the greeting's sport switch (a server sport key such as \"nba\"); a hint for the default sport. */\n rememberedSport?: string\n /** Onboarding presets stage 2: set only by a preset tool's Send (contract §3). */\n preset?: ChatPreset\n page?: PageContext\n}\n\nexport type SignalType =\n | 'MatchPageView' | 'PlayerPageView' | 'TeamPageView' | 'MarketView'\n | 'SearchQuery' | 'SessionDepth' | 'TimeOnPage' | 'InsightViewed'\n | 'InsightMarketClicked' | 'BetPlacedFromInsight' | 'InsightScrollDepth'\n | 'ToolCall' | 'EntityMention' | 'Handoff' | 'FollowUpQuery' | 'RecommendationDismissed'\n\nexport type SignalEntityType =\n | 'Match' | 'Team' | 'Player' | 'Competition' | 'Market'\n | 'Article' | 'Session' | 'Query' | 'Conversation'\n\nexport interface SignalInput {\n signalType: SignalType\n entityType: SignalEntityType\n /** Either this or entityId is required -- an operator's UI mostly knows a display name. */\n entityName?: string\n /** Either this or entityName is required -- a dashboard tile knows its entity by id. */\n entityId?: string\n operatorUserId?: string\n anonymousUserId?: string\n /** Greeting dashboard layout this signal came from, when it is a dashboard tap. */\n dashboardLayout?: string\n /** Zero-based tile position within the dashboard, when it is a dashboard tap. */\n tileIndex?: number\n /** Wire sport key ('nba'); absent means football. Set by the widget, never by an operator. */\n sport?: string\n}\n\nexport type { SlipSport }\n\nexport interface SlipSelection {\n matchOddsId: number\n matchId: number\n oddsDecimal: number\n quotedAtUtc?: string\n insightId?: string\n conversationId?: string\n sport?: SlipSport\n}\n\nexport type AddToSlipRejectReason =\n | 'suspended' | 'closed' | 'login_required'\n | 'not_found' | 'limit' | 'unsupported'\n\nexport type AddToSlipResult =\n | { status: 'added'; slip?: { selectionCount: number; totalOddsDecimal?: number } }\n | { status: 'duplicate' }\n | { status: 'price_changed'; newOddsDecimal: number; accepted: boolean }\n | { status: 'rejected'; reason: AddToSlipRejectReason; message?: string }\n\nexport type AddToSlipHandler = (\n selection: SlipSelection,\n) => Promise<AddToSlipResult | void> | AddToSlipResult | void\n\nconst REJECT_REASONS = ['suspended', 'closed', 'login_required', 'not_found', 'limit', 'unsupported']\n\nexport function isAddToSlipResult(v: unknown): v is AddToSlipResult {\n if (typeof v !== 'object' || v === null) return false\n const o = v as Record<string, unknown>\n switch (o.status) {\n case 'added':\n case 'duplicate':\n return true\n case 'price_changed':\n return typeof o.newOddsDecimal === 'number'\n && Number.isFinite(o.newOddsDecimal)\n && typeof o.accepted === 'boolean'\n case 'rejected':\n return typeof o.reason === 'string'\n && REJECT_REASONS.includes(o.reason)\n default:\n return false\n }\n}\n","export interface SportSpec { readonly slipPrefix: string; readonly monitorPrefix: string; readonly label: string; readonly slippable: boolean; readonly wireKey: string | undefined }\n\nexport const SPORTS = {\n basketball: { slipPrefix: 'bb:', monitorPrefix: 'nba:', label: 'NBA', slippable: true, wireKey: 'nba' },\n americanfootball: { slipPrefix: 'af:', monitorPrefix: 'nfl:', label: 'NFL', slippable: true, wireKey: 'nfl' },\n} as const satisfies Record<string, SportSpec>\n\nexport type NonFootballSport = keyof typeof SPORTS\n/** The sport keys the server accepts on a signal or widget event: only a sport with a wireKey. */\nexport type WireSport = NonNullable<(typeof SPORTS)[NonFootballSport]['wireKey']>\nexport type QualifiedType = 'game' | 'team' | 'player' | 'competition' | 'market'\n/** The sports whose prices can reach an operator slip or a pin: those the map marks slippable. */\nexport type SlipSport = { [K in NonFootballSport]: (typeof SPORTS)[K]['slippable'] extends true ? K : never }[NonFootballSport]\n\n/** undefined means football: every sport the map does not know is football. */\nexport function sportOf(v: unknown): NonFootballSport | undefined {\n return typeof v === 'string' && Object.prototype.hasOwnProperty.call(SPORTS, v) ? (v as NonFootballSport) : undefined\n}\n\n/** True for football (no sport) and for a sport the map marks slippable: the only cases that may pin or slip. */\nexport function mayPinOrSlip(v: unknown): boolean {\n const sport = sportOf(v)\n return sport === undefined || SPORTS[sport].slippable\n}\n\n/** The sport when it may take a slip pick or a pin; undefined for football and for a sport that never does. */\nexport function slipSportOf(v: unknown): SlipSport | undefined {\n const sport = sportOf(v)\n return sport !== undefined && SPORTS[sport].slippable ? (sport as SlipSport) : undefined\n}\n\n/** The key the server reads as `sport`; undefined for football and for a sport without a wireKey. */\nexport function toWireSport(v: unknown): WireSport | undefined {\n const sport = sportOf(v)\n return sport === undefined ? undefined : (SPORTS[sport].wireKey as WireSport | undefined)\n}\n\n/** A server sport key (a set's `sport`) back to the key the server reads on a signal; undefined unless the map carries it as a wireKey. */\nexport function fromWireSport(v: unknown): WireSport | undefined {\n return typeof v === 'string' && Object.values(SPORTS).some((s) => s.wireKey === v) ? (v as WireSport) : undefined\n}\n\nexport function qualifiedId(sport: unknown, type: QualifiedType, id: string): string {\n const wire = toWireSport(sport)\n return wire ? `${wire}:${type}:${id}` : id\n}\n"],"mappings":"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","names":["isAbort"]}
|