@claudinho/core 0.8.11 → 0.8.13
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/dist/index.d.ts +12 -24
- package/dist/index.js +37 -18
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -847,6 +847,17 @@ declare function deriveFavorite(outcomes: MarketOutcome[]): MarketFavorite | und
|
|
|
847
847
|
* draw line (a 90' group result must price the draw).
|
|
848
848
|
*/
|
|
849
849
|
declare function mapsCleanly(match: Match, outcomes: MarketOutcome[]): boolean;
|
|
850
|
+
/**
|
|
851
|
+
* Is a (possibly cached/looked-up) signal safe to RENDER for THIS fixture? A
|
|
852
|
+
* signal is keyed and stored by match id, but display labels are taken from the
|
|
853
|
+
* *current* Match — so a cached signal must be re-checked against the fixture
|
|
854
|
+
* actually being shown. The guard: same match id AND the outcomes still map to
|
|
855
|
+
* the fixture's real teams. This fails closed when a knockout slot the feed
|
|
856
|
+
* resolved earlier later degrades back to a 🏳️ placeholder (the signal's own
|
|
857
|
+
* `ambiguous` flag was decided at fetch time, against the resolved match, so it
|
|
858
|
+
* can't catch this on its own).
|
|
859
|
+
*/
|
|
860
|
+
declare function marketSignalRendersFor(match: Match, signal: MarketSignal): boolean;
|
|
850
861
|
/** Sanity check: ≥2 priced outcomes whose probabilities sum to ~1. */
|
|
851
862
|
declare function hasSaneDistribution(outcomes: MarketOutcome[]): boolean;
|
|
852
863
|
/** Is the signal older than the freshness window? Unparseable timestamps are stale. */
|
|
@@ -952,29 +963,6 @@ declare class FakeMarketProvider implements MarketProvider {
|
|
|
952
963
|
private synthesize;
|
|
953
964
|
}
|
|
954
965
|
|
|
955
|
-
/**
|
|
956
|
-
* Polymarket public-data adapter — read-only prediction-market signals.
|
|
957
|
-
*
|
|
958
|
-
* STRICT read-only by design: it touches only the public Gamma events/markets
|
|
959
|
-
* data endpoint. No auth, no wallet, no CLOB/order endpoints, no trading, and no
|
|
960
|
-
* outbound links (sourceMarketId is opaque, never a URL). Any network/parse/host
|
|
961
|
-
* error degrades to "no signal" — it never throws.
|
|
962
|
-
*
|
|
963
|
-
* Payload model (verified against the live Gamma API, see
|
|
964
|
-
* docs/POLYMARKET_MARKET_PREDICTIONS.md): a World Cup match is a Gamma EVENT
|
|
965
|
-
* (`fifwc-{home}-{away}-{date}`) whose payload carries the three moneyline
|
|
966
|
-
* BINARY markets — home win / draw / away win. Each is `outcomes: ["Yes","No"]`
|
|
967
|
-
* and the outcome's probability is its "Yes" price.
|
|
968
|
-
*
|
|
969
|
-
* Mapping is by event slug, which is deterministic — so by default the slug is
|
|
970
|
-
* DERIVED from the fixture (team codes + UTC date) and every match attempts
|
|
971
|
-
* enrichment. A hand-curated entry in mapping.2026.json overrides the derived
|
|
972
|
-
* slug for the rare fixture whose slug doesn't follow the pattern. Because the
|
|
973
|
-
* slug is a guess, validation FAILS CLOSED: the returned event must match the
|
|
974
|
-
* requested slug, line up on kickoff, expose the right moneyline markets, and
|
|
975
|
-
* resolve in regular time — otherwise no signal is produced.
|
|
976
|
-
*/
|
|
977
|
-
|
|
978
966
|
/**
|
|
979
967
|
* Optional override of the derived event slug for a fixture whose Polymarket
|
|
980
968
|
* slug doesn't follow `fifwc-{home}-{away}-{date}` (e.g. an abbreviation that
|
|
@@ -1164,4 +1152,4 @@ declare function formatShareBracket(input: ShareBracketInput, options?: ShareBra
|
|
|
1164
1152
|
/** Compact one-line-per-match bracket for narrow share contexts. */
|
|
1165
1153
|
declare function formatBracketCompactLine(mv: BracketMatchView, opts?: BracketFormatOpts): string;
|
|
1166
1154
|
|
|
1167
|
-
export { BRACKET_STAGE_ORDER, type BracketFormatOpts, type BracketMatchNode, type BracketMatchView, type BracketResult, type BracketTopology, type BracketView, type BuildSignalInput, DEFAULT_COMPETITION, DEFAULT_FLAVOR, DEFAULT_MAX_AGE_MS, EspnAdapter, type EspnAdapterOptions, FLAVOR_LEVELS, FakeMarketProvider, type FakeMarketProviderOptions, type FavoriteStrength, type FlavorLevel, type FormatOpts, type GroupStandings, type KnockoutFixturesResult, LIVE_WINDOW_MS, type Lang, type LedgerRow, type LiveResult, type MapContext, type MarketFavorite, type MarketMapping, type MarketMappingTable, type MarketOutcome, type MarketOutcomeKind, type MarketProvider, type MarketSignal, type MarketSignalOptions, type MarketSignalsResult, type Match, type MatchByIdResult, type MatchEvent, type NextFixtureResult, type Outcome, PolymarketProvider, type PolymarketProviderOptions, type ProviderAdapter, type ProviderCapabilities, type PunditPick, type ResolvedParticipant, SHARE_DISCLAIMER, SHARE_HASHTAG, type ShareBracketInput, type ShareBracketOptions, type ShareSnippetInput, type ShareSnippetOptions, type ShareStyle, type ShareTableInput, type SlotRef, type Stage, type StandingRow, type StandingsResult, type Status, type Team, allFixtures, asFlavorLevel, buildBracketTopology, buildBracketView, buildMarketSignal, byKickoff, competitionBase, computeStandings, countdown, currentOrNextFixtureForTeam, deriveFavorite, favoriteStrength, fixturesByDate, fixturesByGroup, fixturesByTeam, fixturesInLiveWindow, flagEmoji, formatBracketCompactLine, formatBracketList, formatBracketMatchLine, formatBracketTree, formatDate, formatKickoff, formatShareBracket, formatShareSnippet, formatShareTable, formatTime, getBracket, getKnockoutFixtures, getLiveMatches, getMarketSignal, getMarketSignals, getMatchById, getMatchesForDate, getNextFixtureForTeam, getStandings, groups, hasSaneDistribution, isFinished, isFlavorLevel, isLive, isReliableMarketSignal, isResolvedNation, isStaleSignal, isValidDate, isValidTimeZone, liveSourceLabel, loadBracketTopology, localDate, makeAdapter, makeMarketProvider, mapEspnEvent, mapsCleanly, marketAttributionText, marketBlock, marketFavoriteText, marketFixtureForTeam, marketLine, marketProbabilityText, marketRelevant, marketSourceLabel, matchFlavor, matchKey, matchLocation, mergeLive, nationToFlag, nationToRegion, nextFixtureForTeam, normalizeLang, normalizeOutcomes, outcomeFromScore, parseStandings, parseTeamSlot, resolveCompetition, resolveMarketSource, resolveTz, sanitizeBundledFixture, scoreline, stageLabel, stageLabelI18n, t };
|
|
1155
|
+
export { BRACKET_STAGE_ORDER, type BracketFormatOpts, type BracketMatchNode, type BracketMatchView, type BracketResult, type BracketTopology, type BracketView, type BuildSignalInput, DEFAULT_COMPETITION, DEFAULT_FLAVOR, DEFAULT_MAX_AGE_MS, EspnAdapter, type EspnAdapterOptions, FLAVOR_LEVELS, FakeMarketProvider, type FakeMarketProviderOptions, type FavoriteStrength, type FlavorLevel, type FormatOpts, type GroupStandings, type KnockoutFixturesResult, LIVE_WINDOW_MS, type Lang, type LedgerRow, type LiveResult, type MapContext, type MarketFavorite, type MarketMapping, type MarketMappingTable, type MarketOutcome, type MarketOutcomeKind, type MarketProvider, type MarketSignal, type MarketSignalOptions, type MarketSignalsResult, type Match, type MatchByIdResult, type MatchEvent, type NextFixtureResult, type Outcome, PolymarketProvider, type PolymarketProviderOptions, type ProviderAdapter, type ProviderCapabilities, type PunditPick, type ResolvedParticipant, SHARE_DISCLAIMER, SHARE_HASHTAG, type ShareBracketInput, type ShareBracketOptions, type ShareSnippetInput, type ShareSnippetOptions, type ShareStyle, type ShareTableInput, type SlotRef, type Stage, type StandingRow, type StandingsResult, type Status, type Team, allFixtures, asFlavorLevel, buildBracketTopology, buildBracketView, buildMarketSignal, byKickoff, competitionBase, computeStandings, countdown, currentOrNextFixtureForTeam, deriveFavorite, favoriteStrength, fixturesByDate, fixturesByGroup, fixturesByTeam, fixturesInLiveWindow, flagEmoji, formatBracketCompactLine, formatBracketList, formatBracketMatchLine, formatBracketTree, formatDate, formatKickoff, formatShareBracket, formatShareSnippet, formatShareTable, formatTime, getBracket, getKnockoutFixtures, getLiveMatches, getMarketSignal, getMarketSignals, getMatchById, getMatchesForDate, getNextFixtureForTeam, getStandings, groups, hasSaneDistribution, isFinished, isFlavorLevel, isLive, isReliableMarketSignal, isResolvedNation, isStaleSignal, isValidDate, isValidTimeZone, liveSourceLabel, loadBracketTopology, localDate, makeAdapter, makeMarketProvider, mapEspnEvent, mapsCleanly, marketAttributionText, marketBlock, marketFavoriteText, marketFixtureForTeam, marketLine, marketProbabilityText, marketRelevant, marketSignalRendersFor, marketSourceLabel, matchFlavor, matchKey, matchLocation, mergeLive, nationToFlag, nationToRegion, nextFixtureForTeam, normalizeLang, normalizeOutcomes, outcomeFromScore, parseStandings, parseTeamSlot, resolveCompetition, resolveMarketSource, resolveTz, sanitizeBundledFixture, scoreline, stageLabel, stageLabelI18n, t };
|
package/dist/index.js
CHANGED
|
@@ -497,6 +497,10 @@ function localDate(iso, tz) {
|
|
|
497
497
|
timeZone: zone
|
|
498
498
|
}).format(new Date(iso));
|
|
499
499
|
}
|
|
500
|
+
function shiftUtcDate(dateISO, days) {
|
|
501
|
+
const [y, m, d] = dateISO.slice(0, 10).split("-").map(Number);
|
|
502
|
+
return new Date(Date.UTC(y ?? 1970, (m ?? 1) - 1, (d ?? 1) + days)).toISOString().slice(0, 10);
|
|
503
|
+
}
|
|
500
504
|
|
|
501
505
|
// src/normalize.ts
|
|
502
506
|
function outcomeFromScore(home, away) {
|
|
@@ -4141,14 +4145,19 @@ async function getBracket(adapter, opts = {}) {
|
|
|
4141
4145
|
source
|
|
4142
4146
|
};
|
|
4143
4147
|
}
|
|
4144
|
-
function shiftUtcDate(dateISO, days) {
|
|
4145
|
-
const [y, m, d] = dateISO.slice(0, 10).split("-").map(Number);
|
|
4146
|
-
return new Date(Date.UTC(y ?? 1970, (m ?? 1) - 1, (d ?? 1) + days)).toISOString().slice(0, 10);
|
|
4147
|
-
}
|
|
4148
4148
|
var EXTRA_TIME_SLACK_MS = 60 * 6e4;
|
|
4149
4149
|
async function marketFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Date()) {
|
|
4150
4150
|
const nowMs = now.getTime();
|
|
4151
|
-
|
|
4151
|
+
let fixtures = allFixtures();
|
|
4152
|
+
let overlayFailed = false;
|
|
4153
|
+
try {
|
|
4154
|
+
if (adapter.fetchWindow) {
|
|
4155
|
+
fixtures = mergeLive(fixtures, await adapter.fetchWindow(KNOCKOUT_WINDOW_START, KNOCKOUT_WINDOW_END));
|
|
4156
|
+
}
|
|
4157
|
+
} catch {
|
|
4158
|
+
overlayFailed = true;
|
|
4159
|
+
}
|
|
4160
|
+
const candidate = fixturesByTeam(code, fixtures).find((m) => {
|
|
4152
4161
|
const k = Date.parse(m.kickoff);
|
|
4153
4162
|
return nowMs >= k && nowMs <= k + LIVE_WINDOW_MS + EXTRA_TIME_SLACK_MS;
|
|
4154
4163
|
});
|
|
@@ -4157,8 +4166,8 @@ async function marketFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Dat
|
|
|
4157
4166
|
const m = r.match ?? candidate;
|
|
4158
4167
|
if (!isFinished(m.status)) return { ...r, match: m };
|
|
4159
4168
|
}
|
|
4160
|
-
const next = nextFixtureForTeam(code, { from: now });
|
|
4161
|
-
return { match: next, degraded:
|
|
4169
|
+
const next = nextFixtureForTeam(code, { from: now, fixtures });
|
|
4170
|
+
return { match: next, degraded: overlayFailed };
|
|
4162
4171
|
}
|
|
4163
4172
|
async function getNextFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Date()) {
|
|
4164
4173
|
const base = allFixtures();
|
|
@@ -4267,6 +4276,9 @@ function mapsCleanly(match, outcomes) {
|
|
|
4267
4276
|
if (match.stage === "GROUP" && !draw) return false;
|
|
4268
4277
|
return true;
|
|
4269
4278
|
}
|
|
4279
|
+
function marketSignalRendersFor(match, signal) {
|
|
4280
|
+
return signal.matchId === match.id && mapsCleanly(match, signal.outcomes);
|
|
4281
|
+
}
|
|
4270
4282
|
function hasSaneDistribution(outcomes) {
|
|
4271
4283
|
const priced = outcomes.filter((o) => Number.isFinite(o.probability) && o.probability > 0);
|
|
4272
4284
|
if (priced.length < 2) return false;
|
|
@@ -4470,12 +4482,15 @@ var PolymarketProvider = class {
|
|
|
4470
4482
|
*/
|
|
4471
4483
|
async resolveOne(match, options) {
|
|
4472
4484
|
const entry = (this.opts.mapping ?? BUNDLED_MAPPING)[match.id];
|
|
4473
|
-
const
|
|
4474
|
-
if (
|
|
4485
|
+
const slugs = entry?.eventSlug ? [entry.eventSlug] : deriveEventSlugs(match);
|
|
4486
|
+
if (slugs.length === 0) return { checked: true };
|
|
4475
4487
|
try {
|
|
4476
|
-
const
|
|
4477
|
-
|
|
4478
|
-
|
|
4488
|
+
for (const slug of slugs) {
|
|
4489
|
+
const event = await this.fetchEvent(slug, options?.timeoutMs);
|
|
4490
|
+
const signal = event ? this.toSignal(match, slug, event, options) : void 0;
|
|
4491
|
+
if (signal) return { signal, checked: true };
|
|
4492
|
+
}
|
|
4493
|
+
return { checked: true };
|
|
4479
4494
|
} catch {
|
|
4480
4495
|
return { checked: false };
|
|
4481
4496
|
}
|
|
@@ -4551,14 +4566,17 @@ var PolymarketProvider = class {
|
|
|
4551
4566
|
return signal.ambiguous ? void 0 : signal;
|
|
4552
4567
|
}
|
|
4553
4568
|
};
|
|
4554
|
-
function
|
|
4569
|
+
function deriveEventSlugs(match) {
|
|
4555
4570
|
const home = match.home.code.toLowerCase();
|
|
4556
4571
|
const away = match.away.code.toLowerCase();
|
|
4557
|
-
if (home === away || home === "tbd" || away === "tbd") return
|
|
4558
|
-
if (!/^[a-z]{3}$/.test(home) || !/^[a-z]{3}$/.test(away)) return
|
|
4559
|
-
const
|
|
4560
|
-
if (!/^\d{4}-\d{2}-\d{2}$/.test(
|
|
4561
|
-
return
|
|
4572
|
+
if (home === away || home === "tbd" || away === "tbd") return [];
|
|
4573
|
+
if (!/^[a-z]{3}$/.test(home) || !/^[a-z]{3}$/.test(away)) return [];
|
|
4574
|
+
const utcDate = match.kickoff.slice(0, 10);
|
|
4575
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(utcDate)) return [];
|
|
4576
|
+
return [
|
|
4577
|
+
`fifwc-${home}-${away}-${utcDate}`,
|
|
4578
|
+
`fifwc-${home}-${away}-${shiftUtcDate(utcDate, -1)}`
|
|
4579
|
+
];
|
|
4562
4580
|
}
|
|
4563
4581
|
function slugToken(m) {
|
|
4564
4582
|
return (m.slug ?? "").toLowerCase().split("-").pop() ?? "";
|
|
@@ -4979,6 +4997,7 @@ export {
|
|
|
4979
4997
|
marketLine,
|
|
4980
4998
|
marketProbabilityText,
|
|
4981
4999
|
marketRelevant,
|
|
5000
|
+
marketSignalRendersFor,
|
|
4982
5001
|
marketSourceLabel,
|
|
4983
5002
|
matchFlavor,
|
|
4984
5003
|
matchKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudinho/core",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.13",
|
|
4
4
|
"description": "Domain model, provider adapters (ESPN), standings, bundled schedule, and the read-only Polymarket market-signal sidecar powering Claudinho. Not affiliated with FIFA or Anthropic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|