Skip to content

weather/src

Mostlyright TypeScript SDK


Mostlyright TypeScript SDK / weather/src

Defined in: packages-ts/weather/src/hosted/fetch.ts:43

A misconfiguration of the opt-in hosted seams (WEATHER_HOSTED_URL / EARNINGS_HOSTED_URL / MOSTLYRIGHT_API_KEY) — surfaced BEFORE any network call so the caller gets a clear, actionable error instead of a raw 401/null.

Mirrors the Python _hosted_client “clear config error” contract (28-31 Task 1, Test 3): a missing seam is a caller/deployment bug, not a transport failure, so it is a distinct typed error a caller can branch on.

  • MostlyRightError

new HostedConfigError(message, options): HostedConfigError

Defined in: packages-ts/weather/src/hosted/fetch.ts:46

string

MostlyRightErrorOptions = {}

HostedConfigError

MostlyRightError.constructor

static defaultErrorCode: string = "HOSTED_CONFIG"

Defined in: packages-ts/weather/src/hosted/fetch.ts:44

Subclass override — the stable string enum surfaced via errorCode.

MostlyRightError.defaultErrorCode


Defined in: packages-ts/weather/src/hosted/fetch.ts:60

A non-2xx (or otherwise failed) response from the hosted API — carries the HTTP status and the server message so the caller can branch (401 → bad key, 429 → global ceiling hit, 5xx → serving down).

Distinct from HostedConfigError (which fires BEFORE the request): this is a transport-layer failure AFTER the request was issued. Mirrors the Python hosted client’s “typed error with status + message” contract (28-31 Test 4).

  • MostlyRightError

new HostedResponseError(message, options): HostedResponseError

Defined in: packages-ts/weather/src/hosted/fetch.ts:66

string

MostlyRightErrorOptions & object = {}

HostedResponseError

MostlyRightError.constructor

static defaultErrorCode: string = "HOSTED_RESPONSE"

Defined in: packages-ts/weather/src/hosted/fetch.ts:61

Subclass override — the stable string enum surfaced via errorCode.

MostlyRightError.defaultErrorCode

readonly status: null | number

Defined in: packages-ts/weather/src/hosted/fetch.ts:64

The HTTP status code (e.g. 401, 429, 500), or null for a network error.

Defined in: packages-ts/weather/src/_fetchers/awc.ts:54

Raw AWC METAR record as returned by the public JSON endpoint.

Fields are documented loosely — the upstream payload is not formally schema-versioned. We pass-through optional fields to the parser (_parsers/awc.ts) which validates them against bounds.

optional altim: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:65

Altimeter setting in hPa.

optional clouds: readonly object[]

Defined in: packages-ts/weather/src/_fetchers/awc.ts:74

optional dewp: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:71

Dewpoint in Celsius.

icaoId: string

Defined in: packages-ts/weather/src/_fetchers/awc.ts:56

Four-letter ICAO identifier (e.g. “KNYC”). REQUIRED.

optional metarType: string

Defined in: packages-ts/weather/src/_fetchers/awc.ts:59

obsTime: number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:58

Observation time as Unix epoch seconds. REQUIRED.

optional precip: null | string | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:80

Precipitation past hour (inches). “T” = trace.

optional qcField: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:82

QC bitmask field.

optional rawOb: null | string

Defined in: packages-ts/weather/src/_fetchers/awc.ts:76

Raw METAR text — includes remarks.

optional slp: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:67

Sea-level pressure in mb/hPa.

optional temp: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:69

Temperature in Celsius.

optional visib: null | string | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:73

Visibility — may be number, “10+”, “1/2”, “2 1/4”, “M1/4”, etc.

optional wdir: string | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:61

Wind direction in degrees, or “VRB” for variable.

optional wgst: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:63

optional wspd: null | number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:62

optional wxString: null | string

Defined in: packages-ts/weather/src/_fetchers/awc.ts:78

Weather codes (e.g. “RA BR”).


Defined in: packages-ts/weather/src/_parsers/cli.ts:24

high_temp_f: null | number

Defined in: packages-ts/weather/src/_parsers/cli.ts:30

Daily high °F, rounded to int. null when missing or out-of-bounds.

issued_at: null | string

Defined in: packages-ts/weather/src/_parsers/cli.ts:46

ISO 8601 UTC issuance time parsed from product[:12], else null.

low_temp_f: null | number

Defined in: packages-ts/weather/src/_parsers/cli.ts:32

Daily low °F, rounded to int. null when missing or out-of-bounds.

observation_date: string

Defined in: packages-ts/weather/src/_parsers/cli.ts:28

Local climate day, YYYY-MM-DD.

product_id: null | string

Defined in: packages-ts/weather/src/_parsers/cli.ts:44

Raw NWS product identifier when present.

report_type: ReportType

Defined in: packages-ts/weather/src/_parsers/cli.ts:34

Inferred report type.

report_type_priority: number

Defined in: packages-ts/weather/src/_parsers/cli.ts:40

Numeric priority for dedup (final=3, ncei_final=2.5, correction=2, preliminary=1, estimated=0). Sourced from CLIMATE_REPORT_TYPE_PRIORITY in @mostlyrightmd/core codegen.

source: "iem"

Defined in: packages-ts/weather/src/_parsers/cli.ts:42

Always "iem" for CLI records.

station_code: string

Defined in: packages-ts/weather/src/_parsers/cli.ts:26

Station code (3-letter NWS or 4-letter ICAO, caller’s choice).


Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:45

Raw record shape returned by IEM cli.py (post-unwrap of {results: [...]}).

We capture only the fields consumed by the parser; everything else is preserved as unknown so forward-compat is automatic when IEM adds new columns.

[key: string]: unknown

optional high: null | number | "" | "M"

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:49

Observed daily high °F. Sentinel: “M” or empty string for missing.

optional low: null | number | "" | "M"

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:51

Observed daily low °F. Sentinel: “M” or empty string for missing.

optional product: null | string

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:53

Product identifier, e.g. “202501160620-KFFC-CDUS42-CLIATL”.

valid: string

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:47

Local climate day, YYYY-MM-DD.


Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:193

readonly callId: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:195

readonly optional eventSourceFactory: EventSourceFactory

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:202

Opens an EventSource for a URL. Default: new EventSource(url) (browser). Injectable so non-browser tests can mock it.

readonly mintToken: (ticker, callId) => Promise<string>

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:199

Mints a short-lived signed-URL token via the authenticated 27-08 path. REQUIRED — a browser EventSource cannot set an Authorization header, so the token is carried on the URL (codex P2).

string

string

Promise<string>

readonly ticker: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:194


Defined in: packages-ts/weather/src/dailyExtremes.types.ts:32

One station-local day’s rollup.

Field names mirror Python DailyExtreme TypedDict exactly so cross-language code reads the same way:

  • date, station, tmin_f, tmax_f, tmean_f, precip_in
  • low_coverage (boolean) and n_obs (int) for debug-friendly gating

date: string

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:34

Station-local calendar date as YYYY-MM-DD.

low_coverage: boolean

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:60

True when n_obs < 12 (matches Python low-coverage gate).

n_obs: number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:62

Count of observation rows that contributed to the day.

precip_in: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:54

Total 1-hour precipitation across the local day, in inches.

source_tmax: null | string

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:58

Source identifier of the row that produced tmax (null on low coverage).

source_tmin: null | string

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:56

Source identifier of the row that produced tmin (null on low coverage).

station: string

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:36

ICAO station code.

tmax_c: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:44

Maximum temperature in °C, or null on low coverage.

tmax_f: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:50

Maximum temperature in °F, or null on low coverage.

tmean_c: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:46

Mean temperature in °C, or null on low coverage.

tmean_f: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:52

Mean temperature in °F, or null on low coverage.

tmin_c: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:42

Minimum temperature in °C, or null on low coverage. This is the settlement-correct quantity Polymarket resolves on (the Python daily_extremes label is Celsius, daily_extremes_tmin_c).

tmin_f: null | number

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:48

Minimum temperature in °F, or null on low coverage.


Defined in: packages-ts/weather/src/dailyExtremes.types.ts:19

optional merge: DailyExtremesMergeMode

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:21

Source merge mode; default "live_v1".


Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:118

  • FetchWithRetryOptions

optional politenessMs: number

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:123

Delay (ms) between successive year requests. Defaults to IEM_CLI_POLITE_DELAY_MS.


Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:73

  • FetchWithRetryOptions

optional politenessMs: number

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:78

Delay (ms) between successive year requests. Defaults to NCEI_POLITE_DELAY_MS. Set to 0 in unit tests.


Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:68

  • FetchWithRetryOptions

optional exactStart: boolean

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:91

When true, fetch the EXACT caller-supplied window — skip the Jan-1 start-normalization AND skip yearly chunking. Issues a single HTTP request to IEM bounded by [start, end+1day) (IEM day2 is exclusive).

Use this for one-off short windows (e.g. obs(strategy="exact_window") — a few-day historical lookup). The default (false) preserves the year-padded path needed for cache-idempotent multi-month / multi-year archive fetches (obs(strategy="warm_cache"), research(), dailyExtremes()).

Regression: GH #57 — without this flag, a 1-day call expanded into a ~734 KB whole-calendar-year fetch and ~75× the payload trimmed in memory downstream.

optional politenessMs: number

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:75

Delay (ms) between successive chunk requests. Defaults to IEM_POLITE_DELAY_MS. Set to 0 in unit tests.

optional reportType: 3 | 4

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:70

3 (METAR, default) or 4 (SPECI).


Defined in: packages-ts/weather/src/_fetchers/earnings.ts:67

A canonical earnings row emitted by parseEarningsPayload. Carries the passthrough schema fields present on the source row plus the SDK overlay.

readonly optional callId: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:69

readonly delivery: "live" | "hosted"

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:85

Delivery channel lineage: "live" or "hosted".

readonly eventTime: null | string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:89

Call air time (ISO-8601 UTC), or null if absent.

readonly optional kalshiCounted: boolean

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:80

readonly knowledgeTime: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:95

Transcript availability (POST-call), ISO-8601 UTC. The PIT invariant (D-27.11): knowledgeTime = transcript availability, NEVER the call air time — a backtest standing before this instant must not see the mention.

readonly optional matchedSurfaceForm: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:77

readonly optional mentionCount: number

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:78

readonly optional offsetSeconds: number

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:74

readonly retrievedAt: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:87

When the SDK retrieved the row (ISO-8601 UTC).

readonly optional roleSource: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:79

readonly optional segment: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:75

readonly optional segmentIndex: number

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:70

readonly source: "earnings_call"

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:83

Shared source identity — always EARNINGS_SOURCE_IDENTITY.

readonly optional speakerName: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:71

readonly optional speakerRole: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:72

readonly optional termCanonical: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:76

readonly optional text: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:73

readonly optional ticker: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:68


Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:57

A canonical LIVE streaming row yielded by consumeEarningsStream.

Mirrors the Python _project_stream_row output. Carries the 27-10 schema delta fields (isFinal / spokenAt / streamSeq / resolutionStatus) plus the SDK overlay (source / knowledgeTime). kalshiCounted is passed through verbatim — the consumer never re-derives it.

readonly optional callId: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:66

readonly event: "transcript_segment" | "fact_delta" | "end_of_call" | "resume_incomplete"

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:59

The SSE event that produced this row.

readonly optional isFinal: boolean

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:81

STT-segment finality ONLY — never settlement authority (codex P2).

readonly optional kalshiCounted: boolean

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:78

Passed through from the fact-delta row — NEVER re-derived client-side.

readonly knowledgeTime: null | string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:87

STT-finalization/publish wallclock (ISO-8601 UTC, >= spokenAt), or null.

readonly optional matchedSurfaceForm: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:74

readonly optional mentionCount: number

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:75

readonly optional offsetSeconds: number

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:71

readonly optional resolutionStatus: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:83

Provisional for a counted fact delta; a live count is never settled.

readonly optional roleSource: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:76

readonly optional segment: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:72

readonly optional segmentIndex: number

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:67

readonly source: "earnings.hosted.stream"

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:61

Always EARNINGS_LIVE_STREAM_SOURCE — provisional live lineage.

readonly optional speakerName: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:68

readonly optional speakerRole: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:69

readonly spokenAt: null | string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:85

Aired event time (ISO-8601 UTC), or null.

readonly streamSeq: null | number

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:63

Monotonic SSE id: = stream_seq (drives Last-Event-ID resume).

readonly optional termCanonical: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:73

readonly optional text: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:70

readonly optional ticker: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:65


Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:177

The minimal EventSource surface the consumer needs — declared structurally so tests can inject a mock without a DOM. Matches the browser EventSource.

onerror: null | (event) => void

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:180

addEventListener(type, listener): void

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:178

string

(event) => void

void

close(): void

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:179

void


Defined in: packages-ts/weather/src/_fetchers/awc.ts:85

  • FetchWithRetryOptions

optional failLoud: boolean

Defined in: packages-ts/weather/src/_fetchers/awc.ts:102

FIX-B (fail-loud): when true, a genuine FAILURE (non-OK HTTP after retry exhaustion, or a network error) THROWS the underlying typed error instead of returning []. Callers that pin source="awc" need this so a fetch failure surfaces loudly rather than masquerading as an empty result.

The default (false/omitted) preserves the historical tolerant contract: failures degrade to [] so merged/latest()/dailyExtremes callers keep running when AWC is down.

Note: a genuinely-empty-but-SUCCESSFUL response (HTTP 200 with zero rows, or a 200 body that is not a JSON array) is NOT a failure — it returns [] in BOTH modes. Empty-success is data truth; only failures throw.

optional hours: number

Defined in: packages-ts/weather/src/_fetchers/awc.ts:87

Lookback window in hours. Default 168 (max). Values above AWC_MAX_HOURS are clamped.


Defined in: packages-ts/weather/src/_fetchers/earnings.ts:242

  • FetchWithRetryOptions

readonly hostedUrl: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:245

The hosted feed base URL. REQUIRED — the SDK ships no default endpoint (the serving layer is the satellite + 27-08).

readonly optional retrievedAt: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:247

Retrieval timestamp override (ISO-8601 UTC). Default: now.


Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:49

Optional knobs for forecastNwp.

readonly optional cycle: string

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:51

Model run datetime — UTC ISO string.

readonly optional fxx: number

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:53

Forecast hour ahead of cycle.

readonly optional member: string

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:61

Ensemble member id (e.g. GEFS "p05", CFS "03"). Mirrors the Python member= kwarg (issue #74); only meaningful for GEFS / CFS. Signature-forward only — TS NWP execution lands in v2.0+.

readonly optional mirror: string

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:55

Force a mirror (e.g. "aws_bdp").


Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:66

One downloaded station-year PSV.

readonly psv: string

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:70

Raw PSV body returned by NCEI (text/plain, pipe-delimited).

readonly stationId: string

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:67

readonly year: number

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:68


Defined in: packages-ts/weather/src/hosted/fetch.ts:97

readonly apiKey: string

Defined in: packages-ts/weather/src/hosted/fetch.ts:102

The MOSTLYRIGHT_API_KEY sent as the x-api-key header on EVERY request. In the MV3 extension this is read from chrome.storage at call time (onboarding UX) — see docs/hosted-api.md. REQUIRED (a missing key throws HostedConfigError before any network call).

readonly optional fetchImpl: FetchLike

Defined in: packages-ts/weather/src/hosted/fetch.ts:109

Injectable fetch (default: the browser/MV3 global fetch). Tests pass a mock; production leaves it undefined and uses the platform fetch.

readonly optional signal: AbortSignal

Defined in: packages-ts/weather/src/hosted/fetch.ts:106

Optional AbortSignal for cancellation (propagated to the underlying fetch). A caller-fired abort surfaces as the abort rejection, NOT a HostedResponseError — callers distinguish cancellation from a server 4xx.


Defined in: packages-ts/weather/src/hosted/fetch.ts:90

The minimal Response surface the shim reads. Matches the browser/MV3 Response (status + ok + .json()).

readonly ok: boolean

Defined in: packages-ts/weather/src/hosted/fetch.ts:91

readonly status: number

Defined in: packages-ts/weather/src/hosted/fetch.ts:92

json(): Promise<unknown>

Defined in: packages-ts/weather/src/hosted/fetch.ts:93

Promise<unknown>

text(): Promise<string>

Defined in: packages-ts/weather/src/hosted/fetch.ts:94

Promise<string>


Defined in: packages-ts/weather/src/earnings/hostedStream.ts:71

readonly apiKey: string

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:78

The MOSTLYRIGHT_API_KEY. REQUIRED. Used to MINT a signed, single-scope ?token= locally (the browser cannot set an x-api-key header — codex P2); the raw key is never placed in the URL.

readonly callId: string

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:82

Call id filter for the stream.

readonly optional eventSourceFactory: EventSourceFactory

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:85

Opens an EventSource for a URL. Default: new EventSource(url) (browser). Injectable so non-browser tests can mock it.

readonly hostedUrl: string

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:74

The earnings serving base URL (EARNINGS_HOSTED_URL) — the deployed 28-12 mr-serving origin. REQUIRED; a missing seam throws HostedConfigError.

readonly optional maxReconnects: number

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:88

Max reconnect attempts after a terminal disconnect before giving up. Default 5. Each attempt re-opens with the last seen Last-Event-ID.

readonly optional signal: AbortSignal

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:91

Optional AbortSignal — when fired, the stream closes the EventSource and ends iteration cleanly (no further reconnect).

readonly ticker: string

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:80

Ticker filter for the stream.


Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:59

One downloaded yearly chunk. The CSV body is forwarded verbatim from the upstream response so the parser can run a downstream pass over it.

readonly chunkEnd: string

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:63

EXCLUSIVE end of this chunk’s range — Jan 1 of the following calendar year.

readonly chunkStart: string

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:61

First day of this chunk’s range (caller’s start for chunk 0; Jan 1 for subsequent).

readonly csv: string

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:65

Raw CSV body returned by IEM (text/plain, comma-separated).


Defined in: packages-ts/weather/src/forecasts/types.ts:44

Optional knobs for iemMosForecasts.

readonly optional fetchFn: (input, init?) => Promise<Response>(input, init?) => Promise<Response>

Defined in: packages-ts/weather/src/forecasts/types.ts:48

Override the fetch function (used by tests).

MDN Reference

URL | RequestInfo

RequestInit

Promise<Response>

MDN Reference

string | URL | Request

RequestInit

Promise<Response>

readonly optional model: IemMosModel

Defined in: packages-ts/weather/src/forecasts/types.ts:46

Default "nbe".


Defined in: packages-ts/weather/src/forecasts/types.ts:14

One IEM MOS forecast row (Phase 17 PLAN-11). camelCase TS / snake_case Python.

readonly dewPointC: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:28

2-m dew point in Celsius.

readonly forecastHour: number

Defined in: packages-ts/weather/src/forecasts/types.ts:24

(validAt - issuedAt) in hours.

readonly issuedAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:20

Model run datetime — UTC ISO string.

readonly model: string

Defined in: packages-ts/weather/src/forecasts/types.ts:18

UPPERCASE model id (e.g. "NBE").

readonly precipProbability: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:34

12-hour probability of precipitation [0, 1].

readonly retrievedAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:40

When the row was fetched — UTC ISO string.

readonly skyCoverPct: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:36

Sky cover %; IEM MOS does not expose this — always null.

readonly source: IemMosSource

Defined in: packages-ts/weather/src/forecasts/types.ts:38

Per-row source identity. Always "iem.archive" for now.

readonly station: string

Defined in: packages-ts/weather/src/forecasts/types.ts:16

ICAO station code (uppercased).

readonly tempC: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:26

2-m temperature in Celsius (null when MOS field is M / missing).

readonly validAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:22

Forecast valid datetime — UTC ISO string.

readonly windDirDeg: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:32

Wind direction in degrees [0, 360).

readonly windSpeedMs: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:30

10-m wind speed in m/s.


Defined in: packages-ts/weather/src/_parsers/iem.ts:67

optional observationTypeOverride: IemObservationTypeOverride

Defined in: packages-ts/weather/src/_parsers/iem.ts:73

Force observation_type to this value regardless of metar text. Used by callers that issue separate report_type=3/4 fetches and therefore know the type per-batch without inspecting the raw text.


Defined in: packages-ts/weather/src/live/latest.ts:14

readonly optional source: null | string

Defined in: packages-ts/weather/src/live/latest.ts:19

Live source to poll. "awc" (default, fastest) or "iem" (~10-min delay; useful when AWC is down). Case-insensitive.


Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:184

The minimal MessageEvent surface: a JSON data string + lastEventId.

readonly data: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:185

readonly optional lastEventId: string

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:186


Defined in: packages-ts/weather/src/_parsers/awc.ts:57

Single observation row, matching specs/observation.json.

Notes on null vs unknown:

  • Every field defaults to null if the upstream record omits it, fails bounds, or fails type parsing. This mirrors the Python parser (no exceptions on bad input — only on missing required keys).
  • source is always the string literal "awc" for AWC-sourced rows (the row-level enum is "awc" | "iem" | "ghcnh"; the .live/.archive suffix is a CATALOG-layer source-id, not a row field).
  • observed_at is ISO 8601 UTC with Z suffix.

readonly altimeter_inhg: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:77

readonly dewpoint_c: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:71

readonly dewpoint_f: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:73

readonly observation_type: "METAR" | "SPECI"

Defined in: packages-ts/weather/src/_parsers/awc.ts:60

readonly observed_at: string

Defined in: packages-ts/weather/src/_parsers/awc.ts:59

readonly peak_wind_dir: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:91

readonly peak_wind_gust_kt: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:90

readonly peak_wind_time: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:92

readonly precip_1hr_inches: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:89

readonly qc_field: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:94

readonly raw_metar: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:95

readonly sea_level_pressure_mb: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:78

readonly sky_base_1_ft: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:80

readonly sky_base_2_ft: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:82

readonly sky_base_3_ft: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:84

readonly sky_base_4_ft: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:86

readonly sky_cover_1: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:79

readonly sky_cover_2: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:81

readonly sky_cover_3: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:83

readonly sky_cover_4: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:85

readonly snow_depth_inches: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:93

readonly source: "ghcnh" | "iem" | "awc"

Defined in: packages-ts/weather/src/_parsers/awc.ts:69

Per-row source tag. Widened in TS-W2 Plan 01 to cover all 3 row-level observation sources (AWC live, IEM ASOS archive, GHCNh archive). Each parser still emits its own literal — AWC emits "awc", IEM ASOS emits "iem", GHCNh emits "ghcnh" — but the shared Observation contract accepts all three so mergeObservations (TS-W2 Plan 04) sees one row shape across sources. Matches Python schema.observation.v1.source enum.

readonly station_code: string

Defined in: packages-ts/weather/src/_parsers/awc.ts:58

readonly temp_c: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:70

readonly temp_f: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:72

readonly visibility_miles: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:87

readonly weather_codes: null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:88

readonly wind_dir_degrees: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:74

readonly wind_gust_kt: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:76

readonly wind_speed_kt: null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:75


Defined in: packages-ts/weather/src/obs.types.ts:78

optional granularity: ObsGranularity

Defined in: packages-ts/weather/src/obs.types.ts:89

Phase 30 30-04 (D-03) — row-level grain. Default "observation" (the per-report rows TS obs() has always returned — byte-stable no-option behavior). "daily" is NOT YET PORTED in TS and throws when passed explicitly; see ObsGranularity.

optional source: ObsSourceFilter

Defined in: packages-ts/weather/src/obs.types.ts:80

Optional source filter. null (default) means all sources merged.

optional strategy: ObsStrategy

Defined in: packages-ts/weather/src/obs.types.ts:82

Strategy mode; default "auto".

optional tzOverride: string

Defined in: packages-ts/weather/src/obs.types.ts:96

Phase 31 31-02 (D-19) — IANA timezone override forwarded to the settlementDate LST-bucketing machinery (mirrors Python obs(..., tz_override=...)). Rarely needed for the canonical station registry (all covered); used for stations whose tz is not in the registry.


Defined in: packages-ts/weather/src/obs.types.ts:104

Single observation row. Field set mirrors the canonical Observation schema (@mostlyrightmd/weather Observation interface) with the METAR-derived fields (temp_f / dewpoint_f / wind_speed_kts / …).

optional dewpoint_c: null | number

Defined in: packages-ts/weather/src/obs.types.ts:110

optional dewpoint_f: null | number

Defined in: packages-ts/weather/src/obs.types.ts:111

observed_at: string

Defined in: packages-ts/weather/src/obs.types.ts:106

optional precip_mm_1h: null | number

Defined in: packages-ts/weather/src/obs.types.ts:115

optional pressure_inhg: null | number

Defined in: packages-ts/weather/src/obs.types.ts:114

optional raw_metar: null | string

Defined in: packages-ts/weather/src/obs.types.ts:116

optional settlementDate: string

Defined in: packages-ts/weather/src/obs.types.ts:126

Phase 31 31-02 (D-19) — ISO YYYY-MM-DD string of the LST settlement day this report belongs to, computed via settlementDateFor (never a raw observed_at[:10] UTC-day slice — a pre-midnight-UTC METAR belongs to the PRIOR LST day for negative-offset US stations). Present on every granularity="observation" row with a parseable observed_at; it is the join key dataset({granularity:"observation"}) uses to LEFT-join daily columns onto each report row.

source: string

Defined in: packages-ts/weather/src/obs.types.ts:107

station: string

Defined in: packages-ts/weather/src/obs.types.ts:105

temp_c: null | number

Defined in: packages-ts/weather/src/obs.types.ts:108

temp_f: null | number

Defined in: packages-ts/weather/src/obs.types.ts:109

optional wind_direction_deg: null | number

Defined in: packages-ts/weather/src/obs.types.ts:113

optional wind_speed_kts: null | number

Defined in: packages-ts/weather/src/obs.types.ts:112


Defined in: packages-ts/weather/src/forecasts/types.ts:112

Optional knobs for openMeteoForecasts.

readonly optional allowLeakage: boolean

Defined in: packages-ts/weather/src/forecasts/types.ts:120

Required true to invoke mode: "seamless".

readonly optional fetchFn: (input, init?) => Promise<Response>(input, init?) => Promise<Response>

Defined in: packages-ts/weather/src/forecasts/types.ts:122

Override the fetch function (used by tests).

MDN Reference

URL | RequestInfo

RequestInit

Promise<Response>

MDN Reference

string | URL | Request

RequestInit

Promise<Response>

readonly optional issuedAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:118

Optional ISO cycle for Single Runs API dispatch.

readonly optional mode: OpenMeteoMode

Defined in: packages-ts/weather/src/forecasts/types.ts:116

Default "training".

readonly optional model: OpenMeteoModel

Defined in: packages-ts/weather/src/forecasts/types.ts:114

Default "gfs_global".


Defined in: packages-ts/weather/src/forecasts/types.ts:126

One Open-Meteo forecast row (Phase 20 schema.forecast.station.v1).

readonly apparentTempC: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:140

readonly capeJkg: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:151

readonly cloudCoverPct: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:146

readonly dewPointC: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:139

readonly directRadiationWm2: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:150

readonly forecastHour: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:137

(validAt - issuedAt) in hours. null when issuedAt is null.

readonly freezingLevelM: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:152

readonly issuedAt: null | string

Defined in: packages-ts/weather/src/forecasts/types.ts:134

Model run datetime — UTC ISO string. May be null for source="open_meteo.seamless" rows (cycle unrecoverable by design).

readonly model: string

Defined in: packages-ts/weather/src/forecasts/types.ts:129

Open-Meteo model key (lowercase, e.g. "gfs_global").

readonly precipitationMm: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:145

readonly precipProbability: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:144

readonly pressureMslHpa: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:148

readonly retrievedAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:157

readonly shortwaveRadiationWm2: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:149

readonly snowDepthM: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:153

readonly source: OpenMeteoSource

Defined in: packages-ts/weather/src/forecasts/types.ts:156

readonly station: string

Defined in: packages-ts/weather/src/forecasts/types.ts:127

readonly surfacePressureHpa: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:147

readonly tempC: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:138

readonly validAt: string

Defined in: packages-ts/weather/src/forecasts/types.ts:135

readonly visibilityM: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:154

readonly weatherCode: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:155

readonly windDirDeg: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:142

readonly windGustsMs: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:143

readonly windSpeedMs: null | number

Defined in: packages-ts/weather/src/forecasts/types.ts:141


Defined in: packages-ts/weather/src/_fetchers/earnings.ts:141

readonly optional retrievedAt: string

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:146

Retrieval timestamp (ISO-8601 UTC). Default: now.

readonly optional source: "earnings.live" | "earnings.hosted"

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:144

Delivery channel source id. Only earnings.hosted is browser-viable here; earnings.live throws (server-only). Default earnings.hosted.


Defined in: packages-ts/weather/src/hosted/satellite.ts:186

readonly apiKey: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:192

The MOSTLYRIGHT_API_KEY sent as x-api-key. REQUIRED.

readonly end: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:198

Event-time window end (ISO-8601).

readonly optional fetchImpl: FetchLike

Defined in: packages-ts/weather/src/hosted/satellite.ts:213

Injectable fetch (tests). Default: the browser/MV3 global.

readonly hostedUrl: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:190

The weather serving base URL (WEATHER_HOSTED_URL) — the deployed 28-30 mr-serving origin. REQUIRED; a missing seam throws HostedConfigError. In the MV3 extension this is build-injected.

readonly optional product: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:205

Optional product id; omit for the server’s per-source default product.

readonly optional retrievedAt: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:209

Retrieval timestamp override (ISO-8601 UTC). Default: now.

readonly satellite: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:203

Explicit satellite id (e.g. "goes16"). REQUIRED: the hosted /satellite endpoint does NOT auto-route (unlike the Python satellite() dispatch, which resolves the family client-side before the hosted call), so the browser shim must name the family or the server returns 422.

readonly optional signal: AbortSignal

Defined in: packages-ts/weather/src/hosted/satellite.ts:211

Optional AbortSignal for cancellation.

readonly start: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:196

Event-time window start (ISO-8601).

readonly station: string | readonly string[]

Defined in: packages-ts/weather/src/hosted/satellite.ts:194

Single station or a list (ICAO/NWS codes). At least one is required.

readonly optional variable: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:207

Optional single-variable filter.


Defined in: packages-ts/weather/src/hosted/satellite.ts:58

A canonical satellite row emitted by satelliteHosted. Mirrors the Python satellite(...) DataFrame row (snake_case wire keys → camelCase props). Field presence follows the wire row: a genuine extracted row carries every field; a degenerate qc_status="suspect" sentinel row (the Python units-contract boundary path) carries empty scan times + pixelRow=-1.

readonly asOfTime: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:83

RFC3339-Z knowledge-time string echoed by the server, or null.

readonly delivery: "hosted"

Defined in: packages-ts/weather/src/hosted/satellite.ts:89

Delivery channel lineage — always "hosted" on this path (D-28.2).

readonly eventTime: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:91

Event time (scan start), ISO-8601 UTC, or null.

readonly ingestedAt: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:81

readonly knowledgeTime: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:93

Knowledge time (leakage anchor), ISO-8601 UTC, or null.

readonly pixelCol: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:69

readonly pixelDqf: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:67

readonly pixelRow: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:68

readonly pixelValue: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:66

readonly pressureLevelHpa: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:65

readonly product: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:62

readonly qcStatus: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:84

readonly retrievedAt: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:95

When the SDK retrieved the row (ISO-8601 UTC).

readonly satellite: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:61

readonly satLonUsed: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:74

readonly scanEndUtc: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:80

Byte-faithful RFC3339-Z scan-end string, or null.

readonly scanStartUtc: null | string

Defined in: packages-ts/weather/src/hosted/satellite.ts:78

Byte-faithful RFC3339-Z scan-start string (event time), or null.

readonly source: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:87

Satellite family identity — passed through verbatim (D2), never re-derived.

readonly sourceObjectKey: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:76

readonly station: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:60

readonly stationLat: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:72

readonly stationLon: null | number

Defined in: packages-ts/weather/src/hosted/satellite.ts:73

readonly units: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:70

readonly variable: string

Defined in: packages-ts/weather/src/hosted/satellite.ts:63


Defined in: packages-ts/weather/src/live/stream.ts:19

readonly optional pollSeconds: null | number

Defined in: packages-ts/weather/src/live/stream.ts:29

Override the polite-floor cadence. Must be >= the per-source floor (AWC=30, IEM=60). When omitted, uses the floor for the active source.

readonly optional signal: AbortSignal

Defined in: packages-ts/weather/src/live/stream.ts:38

Optional AbortSignal for clean cancellation. When fired, the current polite-floor sleep is interrupted and the generator returns. The current in-flight fetch (if any) is allowed to complete — AbortSignal is not threaded into the underlying fetchers (yet) since the v0.14.1 fetchers are synchronous and wrapped via the platform fetch.

readonly optional source: null | string

Defined in: packages-ts/weather/src/live/stream.ts:23

Live source to poll. "awc" (default) or "iem". Case-insensitive.

DailyExtremesMergeMode: "live_v1" | "awc_only" | "iem_only"

Defined in: packages-ts/weather/src/dailyExtremes.types.ts:17

Merge mode controlling which sources contribute observations.

  • live_v1 (default) — IEM ASOS for historical depth + AWC for the recent 168h window. Matches Python merge="live_v1".
  • awc_only — AWC live METAR only. Window must be inside the 168h AWC retention or callers see a sparse return.
  • iem_only — IEM ASOS archive only. No live fallback.

EarningsStreamEvent: typeof SSE_STREAM_EVENTS[number]

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:47


EventSourceFactory: (url) => EventSourceLike

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:191

Factory that opens an EventSource for a fully-formed URL (with ?token=). In the browser this is (url) => new EventSource(url); tests inject a mock.

string

EventSourceLike


FetchLike: (input, init?) => Promise<HostedResponseLike>

Defined in: packages-ts/weather/src/hosted/fetch.ts:79

The minimal fetch surface the shim needs — declared structurally so tests can inject a mock without a global fetch (and so we never reach for a Node HTTP client). Matches the browser/MV3 fetch.

string

Record<string, string>

string

AbortSignal

Promise<HostedResponseLike>


IemCsvRow: Record<string, string>

Defined in: packages-ts/weather/src/_parsers/iem.ts:77

Raw IEM CSV row (header → cell value), all strings before parsing.


IemMosModel: "nbe" | "gfs" | "lav" | "met" | "ecm"

Defined in: packages-ts/weather/src/forecasts/types.ts:11

IEM MOS model enum (matches Python SUPPORTED_MOS_MODELS).


IemMosSource: "iem.archive" | "iem.live"

Defined in: packages-ts/weather/src/forecasts/types.ts:8

Canonical source enum (matches Python source column values).


IemObservationTypeOverride: "METAR" | "SPECI"

Defined in: packages-ts/weather/src/_parsers/iem.ts:65


IsoDate: string

Defined in: packages-ts/weather/src/_fetchers/_iem_chunks.ts:30

ISO 8601 date string, no time component. Format: YYYY-MM-DD.

Brand-style alias — at runtime this is a plain string. Use parseIsoDate when you need the parsed year/month/day integers.


LiveObservation: Omit<Observation, "source"> & object

Defined in: packages-ts/weather/src/live/types.ts:23

Observation row emitted by mostlyright.live.stream and live.latest.

Same shape as the canonical Observation row, but with source narrowed to the live-channel identity tags. The widened-archive "awc" / "iem" / "ghcnh" source values are NOT valid here — that’s the point of the separate type.

readonly source: LiveSourceTag


LiveSource: typeof SUPPORTED_SOURCES[number]

Defined in: packages-ts/weather/src/live/sources.ts:11

Validated source enum derived from SUPPORTED_SOURCES.


LiveSourceTag: typeof SOURCE_IDENTITY_TAGS[LiveSource]

Defined in: packages-ts/weather/src/live/sources.ts:38


NwpModel: "hrrr" | "gfs" | "nbm" | "hrrrak" | "gefs" | "gdas" | "rap" | "rrfs" | "rtma" | "urma" | "cfs" | "ecmwf_ifs_hres" | "ecmwf_ifs_ens" | "ecmwf_aifs_single" | "ecmwf_aifs_ens" | "hrdps" | "rdps" | "gdps" | "geps" | "reps" | "hafs" | "nam" | "href" | "hiresw"

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:18

NWP model enum — mirror of Python SUPPORTED_NWP_MODELS (24 entries).


ObsFrameSource: "merged.live_v1" | "awc" | "iem" | "ghcnh"

Defined in: packages-ts/weather/src/obs.types.ts:53

Frame-level source identity carried on the array obs() returns.

Python stamps df.attrs["source"]; TS has no .attrs on plain arrays, so the returned array carries a non-enumerable frameSource property (see ObsResult). Value mirrors Python:

  • unpinned (source omitted / null) → "merged.live_v1" (the fused-policy frame tag a single-source/pinned schema MUST loudly reject).
  • pinned (source set) → the bare pinned source ("awc" / "iem").

ObsGranularity: "daily" | "observation"

Defined in: packages-ts/weather/src/obs.types.ts:41

Phase 30 30-04 (D-03) — row-level grain for obs().

LOCKED to {"daily", "observation"} — structural row-levels, NOT clock cadences ("hourly" was ruled out as a misnomer: native cadence is per-report incl. SPECI + sub-hourly routines).

TS default = "observation" (DELIBERATE divergence from Python’s "daily" default, D-12). TS obs() today already returns per-report rows with no daily aggregation — the OPPOSITE of Python’s daily default. Mirroring Python’s default VALUE would silently break every existing TS caller (Rob’s browser Kalshi plugin receives per-report rows today). We mirror the CONTRACT (the grain axis + value names), not the default value; each SDK’s default preserves its own prior behavior (documented in docs/source-identity.md, 30-05).

  • "observation" — per-report rows (today’s exact behavior), window- trimmed to the UTC [fromDate, toDate] window. No bucketing/resampling.
  • "daily" — daily aggregation. NOT YET PORTED in the TS SDK; selecting it explicitly throws a documented DataAvailabilityError (see obs.ts). A no-option call NEVER reaches this branch (default is "observation").

ObsResult: ReadonlyArray<ObsRow> & object

Defined in: packages-ts/weather/src/obs.types.ts:63

The array obs() returns, augmented with a non-enumerable frame-level frameSource tag (mirrors Python df.attrs["source"]). The rows themselves are byte-identical to the pre-Phase-30 output — frameSource is a non-enumerable property, so iteration, JSON.stringify, spread, and Object.keys over the elements are all unchanged. Introspect via (result as ObsResult).frameSource.

readonly frameSource: ObsFrameSource


ObsSourceFilter: "awc" | "iem" | "ghcnh" | null

Defined in: packages-ts/weather/src/obs.types.ts:76

Source filter — matches Python tw.weather.obs(source=...) _VALID_SOURCES frozenset {"awc", "iem", "ghcnh"}. null (default) means all sources merged.

Phase 21 21-09 fix-iter-1: ghcnh validates as accepted but is not yet wired in TS (no GHCNh fetcher path in fetchByStrategy); selecting it raises DataAvailabilityError(reason="model_unavailable") rather than silently returning []. Tracking issue: TS-W4 GHCNh fetcher port. The cli value was removed — it is not a valid Python source filter either.


ObsStrategy: "auto" | "exact_window" | "warm_cache" | "hosted"

Defined in: packages-ts/weather/src/obs.types.ts:17

Strategy enum — matches Python verbatim.


OpenMeteoMode: "training" | "live" | "seamless"

Defined in: packages-ts/weather/src/forecasts/types.ts:63

Open-Meteo dispatch mode for openMeteoForecasts.


OpenMeteoModel: "gfs_seamless" | "gfs_global" | "gfs_graphcast025" | "aigfs025" | "hgefs025" | "ncep_hrrr_conus" | "ncep_nbm_conus" | "ncep_nam_conus" | "ecmwf_ifs025" | "ecmwf_ifs_hres" | "ecmwf_aifs025_single" | "dwd_icon_seamless" | "dwd_icon_global" | "dwd_icon_eu" | "dwd_icon_d2" | "dwd_icon_d2_15min" | "meteofrance_seamless" | "meteofrance_arpege_world025" | "meteofrance_arpege_europe" | "meteofrance_arome_france0025" | "meteofrance_arome_france_hd" | "meteofrance_arome_france_hd_15min" | "jma_seamless" | "jma_gsm" | "jma_msm" | "kma_seamless" | "kma_gdps" | "kma_ldps" | "cma_grapes_global" | "bom_access_global" | "ukmo_global_deterministic_10km" | "ukmo_uk_deterministic_2km" | "metno_nordic_pp" | "cmc_gem_gdps" | "cmc_gem_rdps" | "cmc_gem_hrdps"

Defined in: packages-ts/weather/src/forecasts/types.ts:66

The 36 Open-Meteo forecast models in scope (Phase 20 D-02).


OpenMeteoSource: "open_meteo.previous_runs" | "open_meteo.single_run" | "open_meteo.live" | "open_meteo.seamless"

Defined in: packages-ts/weather/src/forecasts/types.ts:56

Open-Meteo source-identity enum (per-endpoint discrimination).


ReportType: "final" | "ncei_final" | "correction" | "preliminary" | "estimated"

Defined in: packages-ts/weather/src/_parsers/cli.ts:22


SatelliteSourceIdentity: typeof SATELLITE_SOURCE_IDENTITIES[number]

Defined in: packages-ts/weather/src/hosted/satellite.ts:49

const AWC_MAX_HOURS: 168 = 168

Defined in: packages-ts/weather/src/_fetchers/awc.ts:45

AWC live serves at most ~168 hours (7 days). Beyond that the endpoint either silently truncates or returns an empty list — use IEM ASOS for history.


const AWC_METAR_URL: "https://aviationweather.gov/api/data/metar" = "https://aviationweather.gov/api/data/metar"

Defined in: packages-ts/weather/src/_fetchers/awc.ts:38

Canonical AWC METAR endpoint.


const EARNINGS_LIVE_STREAM_SOURCE: "earnings.hosted.stream"

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:37

The live delivery-channel source id (D-27.16). Distinct from the post-call earnings.hosted ledger: these rows are PROVISIONAL and firewalled out of every backtest/settlement read on the join side.


const EARNINGS_SOURCE_IDENTITY: "earnings_call"

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:37

The single shared source identity (D-27.2). Live STT + the hosted feed are the SAME upstream public call audio, so both stamp this — they reconcile, they do not mismatch. The delivery field carries the channel lineage.


const GHCNH_BASE_URL: "https://www.ncei.noaa.gov/oa/global-historical-climatology-network/hourly/access" = "https://www.ncei.noaa.gov/oa/global-historical-climatology-network/hourly/access"

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:29

NCEI GHCNh public archive base URL (no trailing slash). Mirrors Python GHCNH_BASE_URL.


const HIGH_TEMP_MAX_F: 150 = 150

Defined in: packages-ts/weather/src/_parsers/cli.ts:18


const HIGH_TEMP_MIN_F: -60 = -60

Defined in: packages-ts/weather/src/_parsers/cli.ts:17

Climate temp bounds from specs/climate.json. Inclusive.


const HOSTED_API_KEY_HEADER: "x-api-key"

Defined in: packages-ts/weather/src/hosted/fetch.ts:32

The auth header the hosted serving middleware (27-08) reads. Matches the server contract (curl -H "x-api-key: $MOSTLYRIGHT_API_KEY" ..., 28-12/28-30).


const HOSTED_STREAM_EVENTS: readonly ["transcript_segment", "fact_delta", "end_of_call", "resume_incomplete"]

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:64

The named SSE events the hosted stream consumer subscribes to (the 28-12 / 27-11 wire contract).


const IEM_BASE_URL: "https://mesonet.agron.iastate.edu/cgi-bin/request/asos.py" = "https://mesonet.agron.iastate.edu/cgi-bin/request/asos.py"

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:34

IEM ASOS request endpoint. Mirrors Python IEM_BASE_URL.


const IEM_CLI_BASE_URL: "https://mesonet.agron.iastate.edu/json/cli.py" = "https://mesonet.agron.iastate.edu/json/cli.py"

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:19

IEM cli.py JSON endpoint. Mirrors Python IEM_CLI_BASE_URL.


const IEM_CLI_POLITE_DELAY_MS: 1000 = 1000

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:25

Polite delay (ms) between range requests. Mirrors Python IEM_CLI_POLITE_DELAY = 1.0 — IEM runs on a university server.


const IEM_POLITE_DELAY_MS: 1000 = 1000

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:41

Polite delay (ms) between consecutive IEM HTTP requests. Mirrors Python IEM_POLITE_DELAY = 1.0 (s) — IEM runs on a university server and documents a 1-sec/IP throttle (see .planning/research/SOURCE-LIMITS.md).


const LOW_TEMP_MAX_F: 130 = 130

Defined in: packages-ts/weather/src/_parsers/cli.ts:20


const LOW_TEMP_MIN_F: -80 = -80

Defined in: packages-ts/weather/src/_parsers/cli.ts:19


const NCEI_POLITE_DELAY_MS: 1000 = 1000

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:37

Polite delay (ms) between consecutive NCEI HTTP requests in range mode. Mirrors Python NCEI_POLITE_DELAY = 1.0 (s). The delay fires AFTER each successful response; 404s and network errors do NOT pay the tax.


const OPEN_METEO_LIVE_URL: "https://api.open-meteo.com/v1/forecast" = "https://api.open-meteo.com/v1/forecast"

Defined in: packages-ts/weather/src/forecasts/open-meteo.ts:33


const OPEN_METEO_MODELS: ReadonlySet<OpenMeteoModel>

Defined in: packages-ts/weather/src/forecasts/open-meteo-models.ts:11

The canonical 36-model set (D-02 set-equality lock).


const OPEN_METEO_PREVIOUS_RUNS_URL: "https://previous-runs-api.open-meteo.com/v1/forecast" = "https://previous-runs-api.open-meteo.com/v1/forecast"

Defined in: packages-ts/weather/src/forecasts/open-meteo.ts:31


const OPEN_METEO_SEAMLESS_URL: "https://historical-forecast-api.open-meteo.com/v1/forecast" = "https://historical-forecast-api.open-meteo.com/v1/forecast"

Defined in: packages-ts/weather/src/forecasts/open-meteo.ts:34


const OPEN_METEO_SINGLE_RUNS_URL: "https://single-runs-api.open-meteo.com/v1/forecast" = "https://single-runs-api.open-meteo.com/v1/forecast"

Defined in: packages-ts/weather/src/forecasts/open-meteo.ts:32


const POLITE_FLOORS_S: Readonly<Record<LiveSource, number>>

Defined in: packages-ts/weather/src/live/sources.ts:21

Minimum allowed poll cadence per source, in seconds.

  • AWC: 30s — aviationweather.gov has no documented rate limit but 30s is the empirically-validated floor that won’t trip anti-abuse heuristics.
  • IEM: 60s — mesonet.agron.iastate.edu is a university server; IEM docs explicitly ask for reasonable headroom above 1 req/s.

const SATELLITE_SOURCE_IDENTITIES: readonly ["noaa_goes", "jma_himawari", "noaa_viirs", "eumetsat_meteosat"]

Defined in: packages-ts/weather/src/hosted/satellite.ts:42

The satellite family source identities the hosted rows carry (D2 — one identity per instrument family, mirror-invariant). Informational; the shim passes source through verbatim (never re-derives it).


const SOURCE_IDENTITY_TAGS: object

Defined in: packages-ts/weather/src/live/sources.ts:33

Canonical per-source source field tag emitted on every observation row.

"awc.live" / "iem.live" are the live-channel identity tags — distinct from the archive-channel "awc" / "iem" written by the historical fetchers. Cross-SDK parity: these match Python SOURCE_IDENTITY_TAGS.

readonly awc: "awc.live" = "awc.live"

readonly iem: "iem.live" = "iem.live"


const SSE_STREAM_EVENTS: readonly ["transcript_segment", "fact_delta", "end_of_call", "resume_incomplete"]

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:40

The named SSE events the consumer understands (the 27-11 wire contract).


const SSID_COLUMNS: readonly ["temperature_Source_Station_ID", "dew_point_temperature_Source_Station_ID", "wind_speed_Source_Station_ID", "wind_direction_Source_Station_ID", "sea_level_pressure_Source_Station_ID", "altimeter_Source_Station_ID", "visibility_Source_Station_ID", "sky_cover_summation_1_Source_Station_ID", "sky_cover_summation_2_Source_Station_ID", "sky_cover_summation_3_Source_Station_ID", "sky_cover_summation_4_Source_Station_ID"]

Defined in: packages-ts/weather/src/_parsers/_station_translator.ts:22

Source_Station_ID column priority. Order matches Python _SSID_COLUMNS tuple at _ghcnh.py:45-57 EXACTLY (temperature first, then dew_point, wind_speed, wind_direction, sea_level_pressure, altimeter, visibility, then four sky_cover_summation layers).


const SUPPORTED_SOURCES: readonly ["awc", "iem"]

Defined in: packages-ts/weather/src/live/sources.ts:8

Canonical ordered tuple of supported sources. Order matters — keep AWC first.


const version: "1.15.0" = "1.15.0"

Defined in: packages-ts/weather/src/index.ts:12

Placeholder version string from the TS-W0 Wave 1 scaffold. The authoritative package version lives in package.json#version (currently 0.1.0-rc.7); this constant has not been bumped.

awcToObservation(m): null | Observation

Defined in: packages-ts/weather/src/_parsers/awc.ts:287

Convert one raw AWC METAR record into the canonical observation row.

Returns null if the record is missing icaoId or obsTime, or if the station code can’t be resolved via icaoToStationCode + STATION_CODE_RE, or if obsTime produces an out-of-range date.

Otherwise returns a fully-typed Observation with every field either a validated value or null. Never throws.

AwcMetarRaw

null | Observation


buildIemUrl(stationCode, start, end, reportType): string

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:121

Build the IEM ASOS download URL for one (chunk, report_type) request.

Param shape and ordering are byte-faithful to Python _build_iem_url: station, data, tz, format, latlon, elev, missing, trace, direct, report_type, year1, month1, day1, year2, month2, day2.

Month/day are emitted WITHOUT zero-padding (Python uses bare {start.month}, not {start.month:02d}) — preserve byte-equivalence on URL snapshots.

end is the EXCLUSIVE end (already adjusted by the chunker to Jan 1 of the following calendar year).

string

string

string

number

string


consumeEarningsStream(baseUrl, options): AsyncGenerator<EarningsStreamRow, void, void>

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:232

Consume the live earnings SSE feed as an async iterable of canonical rows.

Mints a short-lived ?token= (codex P2 — EventSource cannot set headers), opens new EventSource("/stream?...&token=…"), subscribes to the transcript_segment + fact_delta named events, and yields projected rows in stream_seq order. Heartbeats (: ping comments) are ignored by EventSource natively. end_of_call closes the stream and ends iteration. resume_incomplete is surfaced as a row (the caller reconciles from the ledger) — never a silent gap.

Browser/MV3-viable: EventSource + JSON only. No Node built-ins.

string

ConsumeEarningsStreamOptions

AsyncGenerator<EarningsStreamRow, void, void>


dailyExtremes(station, fromDate, toDate, opts): Promise<readonly DailyExtremeRow[]>

Defined in: packages-ts/weather/src/dailyExtremes.ts:268

Compute per-day tmin/tmax/tmean/precip for a station’s window.

Matches Python mostlyright.international.daily_extremes signature. Day-bucketing uses the station’s IANA local tz from the STATIONS registry; US ASOS stations get integer-°F precision (Phase 18 invariant); other stations get 0.1-precision values.

string

4-letter ICAO (e.g. “KNYC”, “EGLL”) or 3-letter NWS registry code (e.g. “NYC”) — parity with Python daily_extremes(), which accepts both. Output rows carry the ICAO regardless of input form (Python parity).

string

ISO date YYYY-MM-DD (inclusive, station-local)

string

ISO date YYYY-MM-DD (inclusive, station-local)

DailyExtremesOptions = {}

optional merge mode (default "live_v1")

Promise<readonly DailyExtremeRow[]>

array of DailyExtremeRow, one per station-local day

Error if station is not in the STATIONS registry


downloadCli(stationIcao, year, opts): Promise<readonly CliRawRecord[]>

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:106

Download IEM CLI JSON for one station-year.

URL: ${IEM_CLI_BASE_URL}?station={icao}&year={year}.

Response may be wrapped as {"results": [...]} — we unwrap and return the inner array so downstream parsers always see the same shape.

Throws NotFoundError on HTTP 404 (no data for that year); downloadCliRange catches and continues. Other transport errors propagate as the structured exceptions defined by fetchWithRetry.

string

number

FetchWithRetryOptions = {}

Promise<readonly CliRawRecord[]>


downloadCliRange(stationIcao, startYear, endYear, opts): Promise<readonly CliRawRecord[]>

Defined in: packages-ts/weather/src/_fetchers/iem-cli.ts:136

Download CLI records for an inclusive year range.

Skips 404s (IEM “no data for this year”) so multi-year backfills do not abort when a station has gaps — mirrors Python’s download_cli_range 404-skip behavior. Other HTTP errors propagate.

Between requests we sleep politenessMs (default IEM_CLI_POLITE_DELAY_MS).

string

number

number

DownloadCliRangeOptions = {}

Promise<readonly CliRawRecord[]>


downloadGhcnh(stationId, year, opts): Promise<GhcnhYearResult>

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:91

Download a NOAA GHCNh PSV for one station-year.

URL: ${GHCNH_BASE_URL}/by-year/{year}/psv/GHCNh_{stationId}_{year}.psv.

string

number

FetchWithRetryOptions = {}

Promise<GhcnhYearResult>

when NCEI returns 404 (no data for this station-year). Callers that want 404-as-skip behavior should use downloadGhcnhRange.

If stationId does not match GHCNH_STATION_ID_RE.

Whatever fetchWithRetry propagates on persistent network/HTTP errors.


downloadGhcnhRange(stationId, startYear, endYear, opts): Promise<readonly GhcnhYearResult[]>

Defined in: packages-ts/weather/src/_fetchers/ghcnh.ts:114

Download GHCNh PSVs for an inclusive year range.

Iterates [startYear, endYear]. Years that return 404 (no data for that station-year) are silently skipped — they do NOT appear in the output array. Other HTTP errors propagate.

endYear < startYear returns [] with zero HTTP requests.

Polite delay fires AFTER each successful response only.

string

number

number

DownloadGhcnhRangeOptions = {}

Promise<readonly GhcnhYearResult[]>


downloadIemAsos(stationCode, start, end, opts): Promise<readonly IemChunkResult[]>

Defined in: packages-ts/weather/src/_fetchers/iem-asos.ts:184

Download yearly chunks of IEM ASOS data for one station, returning the raw CSV bodies in chunker-natural order.

The caller’s inclusive [start, end] is normalized internally to [date(start.year, 1, 1), end] and split into per-calendar-year EXCLUSIVE-end chunks via yearlyChunksExclusiveEnd. Each chunk fires one HTTP request to the IEM ASOS endpoint, with a polite delay between successful responses (default IEM_POLITE_DELAY_MS).

Errors propagate from fetchWithRetry — 4xx/5xx after retry exhaustion are NOT swallowed (the IEM ASOS path is parity-critical; silent failure would manifest as missing observation rows downstream).

string

string

string

DownloadIemAsosOptions = {}

Promise<readonly IemChunkResult[]>

If reportType is not 3 (METAR) or 4 (SPECI).

If stationCode does not match ^[A-Z]{3,4}$ (path-traversal / URL-injection defense).

Whatever fetchWithRetry propagates on persistent network/HTTP errors.


extractStationCode(row): null | string

Defined in: packages-ts/weather/src/_parsers/_station_translator.ts:65

Walk SSID_COLUMNS in priority order and return the first non-null result from ghcnhStationToCode. Returns null if every column misses.

Readonly<Record<string, string>>

null | string


fetchAwcMetars(stationIcaos, opts): Promise<readonly AwcMetarRaw[]>

Defined in: packages-ts/weather/src/_fetchers/awc.ts:136

Fetch recent METARs from AWC for one or more ICAO stations.

Returns the raw JSON array as-is (typed as AwcMetarRaw[]); compose with awcToObservation from ../_parsers/awc.ts to map each entry to the observation row schema.

Behaviour mirrors Python fetch_awc_metars (tolerant default mode):

  • empty stationIcaos → return [] immediately, no HTTP issued
  • 4xx after retry exhaustion → []
  • 5xx / network errors after retry budget → []
  • non-array JSON body → []
  • NEVER throws (callers want graceful degradation)

FIX-B: pass { failLoud: true } to opt into fail-loud mode — a genuine FAILURE (non-OK HTTP after retries, or a network error) THROWS a typed AwcFetchError instead of returning []. Empty-but-successful responses (HTTP 200 zero rows / non-array body) still return [] in both modes. Only the pinned source="awc" path in obs() uses this; all other callers keep the tolerant swallow-into-[] contract.

readonly string[]

FetchAwcOptions = {}

Promise<readonly AwcMetarRaw[]>


fetchEarningsHosted(ticker, eventDate, options): Promise<readonly EarningsRow[]>

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:263

Fetch + parse the hosted earnings feed for a ticker on an event date.

Mirrors awc.ts graceful-degradation discipline: returns [] on 4xx, timeout, exhausted retries, or a non-JSON/malformed body — NEVER throws for a transport/parse failure (a caller AbortSignal still propagates). Rows are byte-equivalent to the Python EarningsAdapter.from_rows(source="earnings.hosted") output; only the delivery lineage differs between live and hosted.

Browser-viable: fetch + JSON only. For endpoints without CORS headers, run behind a Chrome MV3 service worker (host_permissions) or a CORS proxy — same posture as fetchAwcMetars.

string

string

FetchEarningsHostedOptions

Promise<readonly EarningsRow[]>


fetchEarningsLive(): never

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:323

The LIVE capture+STT source is python_only / server-only and NOT ported to TS (faster-whisper + ffmpeg are not browser-viable — D-27.5). This stub exists so a caller reaching for the live source gets a clear, typed error rather than a silent gap. Use the Python SDK mostlyrightmd-weather[earnings] for on-device STT, or fetchEarningsHosted for the hosted feed.

never


forecastNwp(station, model, _opts): Promise<never>

Defined in: packages-ts/weather/src/forecasts/nwp-stub.ts:122

Fetch a gridded NWP forecast — v1.x stub, deferred to v2.0+.

string

NwpModel

ForecastNwpOptions = {}

Promise<never>

⚠️ Not yet implemented in TypeScript. This function exists so callers can write code against the future-stable signature, but it throws on every call. Use the Python SDK (mostlyright>=1.0) for gridded NWP today — it wires the NCEP family (HRRR, GFS, NBM, RAP, RRFS, …) end-to-end.

Why deferred: GRIB2 decode requires native libraries (eccodes C library or cfgrib Python wrapper). No production-ready browser-side decoder exists in May 2026; a WASM port’s compile time + bundle size are impractical for v1.x. v2.0+ tracks the GRIB2 ecosystem maturity.

Workaround paths:

  • 7 major US stations (KNYC, KLAX, KORD, KMIA, KDEN, KSEA, KATL) → iemMosForecasts ships MOS-based forecasts that solve most use cases. The error hint includes this pointer automatically.
  • Everything else → use the Python SDK (pip install mostlyrightmd-weather).

NwpNotAvailableError on every call (v1.x). The error is a subclass of DataAvailabilityError, so existing catch (e instanceof DataAvailabilityError) paths continue to catch it. The thrown instance carries typed .station and .model properties for log/error attribution.

docs/nwp-forecasts.md for the full architectural rationale, the supported-model list, and the v2.0+ roadmap.


ghcnhStationToCode(sourceStationId): null | string

Defined in: packages-ts/weather/src/_parsers/_station_translator.ts:46

Extract the 3-letter station code from a GHCNh Source_Station_ID value.

"ICAO-KJFK""JFK" (strip prefix, apply ICAO→code conversion) "744860-94789"null (WMO USAF-WBAN format, no ICAO prefix) "" / "ICAO-"null

Returns null for any input that does not resolve to a value matching STATION_CODE_RE (3-4 uppercase letters).

string

null | string


helloWeather(): string

Defined in: packages-ts/weather/src/index.ts:20

Smoke-test export from the TS-W0 Wave 1 scaffold. Returns the literal string "hello @mostlyrightmd/weather". Retained so the published package has at least one importable runtime export until the scaffold is removed in a later phase.

string


hostedFetchJson(url, options): Promise<unknown>

Defined in: packages-ts/weather/src/hosted/fetch.ts:147

Issue a GET against the hosted API, adding the MOSTLYRIGHT_API_KEY header, and parse the JSON body.

MV3-safe: uses only the browser/MV3 fetch + JSON — no node:*, no http/https, no Buffer. The API key is sent as x-api-key on every request (H4: the key is a public secret; abuse is bounded server-side by the global request ceiling, not by this shim).

string

HostedFetchOptions

Promise<unknown>

when apiKey is empty/missing, or when no fetch is available and none was injected — surfaced BEFORE any request.

when the response is non-2xx, or the body is not valid JSON — carries the HTTP status + server message. A caller-fired AbortSignal rejection is re-thrown as-is (not wrapped), so cancellation is distinguishable from a server error.


hostedStream(options): AsyncGenerator<EarningsStreamRow, void, void>

Defined in: packages-ts/weather/src/earnings/hostedStream.ts:158

Consume the earnings live /stream SSE feed with Last-Event-ID reconnect.

Opens new EventSource("${EARNINGS_HOSTED_URL}/stream?...&apiKey=…"), subscribes to the named events, yields projected rows tagged source="earnings.hosted.stream", and tracks the last seen event id. On a terminal disconnect (the 3600s Cloud Run cut, an instance swap) it RE-OPENS a fresh EventSource carrying the last seen id as lastEventId= so the 28-12 server replays the buffered tail — ZERO events lost across the cut. Iteration ends on end_of_call, on signal abort, or after maxReconnects failed reconnects.

Browser/MV3-viable: EventSource + JSON only. No Node built-ins.

HostedStreamOptions

AsyncGenerator<EarningsStreamRow, void, void>

when EARNINGS_HOSTED_URL / apiKey is missing — surfaced BEFORE the first connection.

when reconnection is exhausted (maxReconnects reached) — the last transport error is re-thrown so the caller sees the failure, not a silent gap.


icaoToStationCode(icao): string

Defined in: packages-ts/weather/src/_parsers/awc.ts:107

Strip the leading K from 4-letter CONUS ICAO codes to get the 3-letter NWS station code (KNYCNYC). Non-K-prefixed codes pass through unchanged after .toUpperCase().

string

string


iemMosForecasts(station, fromDate, toDate, opts): Promise<IemMosRow[]>

Defined in: packages-ts/weather/src/forecasts/iem-mos.ts:177

Fetch IEM MOS forecasts for station in [fromDate, toDate].

Mirrors Python fetch_iem_mos(...). Iterates the model’s runtime-hour grid (NBE moved from {01,07,13,19}Z to {00,06,12,18}Z on 2026-05-05; other models use {00,06,12,18}Z), GETs the JSON endpoint, and projects rows to IemMosRow.

404 responses are silently skipped (many runtimes have no MOS data). Empty input range returns [].

string

string

string

IemMosOptions = {}

Promise<IemMosRow[]>

Error if model is not in SUPPORTED_MODELS.


iemToObservation(row, opts): null | Observation

Defined in: packages-ts/weather/src/_parsers/iem.ts:193

Convert one IEM CSV row (header→cell dict) into the canonical Observation row. Returns null if the row should be skipped:

  • station missing/M, or doesn’t match STATION_CODE_RE after K-strip
  • timestamp unparseable / out-of-range
  • ALL 4 key vars (raw tmpf, raw dwpf, wind_speed, slp) missing

Throws on bad observationTypeOverride (Python L152-156 parity).

Output dict-key order is preserved verbatim — matters for downstream byte-stable JSON snapshot diffs.

IemCsvRow

IemToObservationOptions = {}

null | Observation


inferReportType(product, observationDate): ReportType

Defined in: packages-ts/weather/src/_parsers/cli.ts:129

Infer report type from product timestamp vs observation date.

Rules (byte-faithful port of Python _climate.infer_report_type):

  • No product → "preliminary" (safe default).
  • Unparseable product or observation date → "preliminary".
  • Issued same day as observation → "preliminary".
  • Issued the next day, 04:00–10:00 UTC → "final" (overnight CLI window).
  • Issued the next day outside that window → "correction".
  • Issued >1 day later → "correction".

undefined | null | string

string

ReportType


isLiveSource(s): s is “iem” | “awc”

Defined in: packages-ts/weather/src/live/sources.ts:64

Type guard: narrow a string to LiveSource.

string

s is “iem” | “awc”


joinHostedUrl(baseUrl, path): string

Defined in: packages-ts/weather/src/hosted/fetch.ts:237

Join a base URL and a path, tolerating a trailing slash on the base and a leading slash on the path (so WEATHER_HOSTED_URL="https://x/" + /satellite yields https://x/satellite, never a double slash). Query strings pass through unchanged on the path.

string

string

string


latest(station, opts): Promise<LiveObservation>

Defined in: packages-ts/weather/src/live/latest.ts:37

Return the most-recent observation row for station from a SINGLE source.

Same fetch path as stream, but returns once instead of looping. Use this for cron-style polling where you want one fresh observation per invocation.

string

ICAO ("KNYC") or 3-letter US ID ("NYC"). Case-insensitive.

LatestOptions = {}

Optional { source }.

Promise<LiveObservation>

Error when opts.source is unknown.

NoLiveDataError when the upstream returned no observations for the station — payload carries the resolved station and live source tag for branching.


mapCloudCover(cover): null | string

Defined in: packages-ts/weather/src/_parsers/awc.ts:121

Map AWC cloud-cover token to the standard abbreviation set.

  • Accepts {CLR, SKC, FEW, SCT, BKN, OVC, VV}
  • CAVOKCLR
  • everything else (incl. null/undefined) → null

undefined | null | string

null | string


mintStreamToken(apiKey, ticker, callId, ttlSeconds): Promise<string>

Defined in: packages-ts/weather/src/earnings/streamToken.ts:52

Mint a short-TTL signed-URL token scoped to ONE (ticker, callId).

Byte-identical to services/earnings/sse.py::mint_stream_token so the hosted /stream server’s verify_stream_token accepts it. The token is a single-scope, ttlSeconds-lived credential (default 60s) — NOT a long-lived bearer key. Mint a FRESH token per connection (each reconnect after the 3600s Cloud Run cut must re-mint, since the prior token has expired).

string

the MOSTLYRIGHT_API_KEY (the HMAC signing secret).

string

issuer ticker the token is scoped to.

string

call id the token is scoped to.

number = 60

token lifetime in seconds (default 60, matching the server).

Promise<string>

base64url(msg).base64url(sig).


obs(rawStation, fromDate, toDate, opts): Promise<ObsResult>

Defined in: packages-ts/weather/src/obs.ts:319

Fetch raw observations for a station’s window.

Matches Python tw.weather.obs(station, start, end, source=None, strategy='auto', granularity='observation') signature. The strategy enum selects between the smart-router’s three concrete fetch paths.

Phase 30 30-04 (D-03): the returned array carries a non-enumerable frameSource tag ("merged.live_v1" when unpinned, the bare source when pinned) mirroring Python’s df.attrs["source"]. The rows themselves are byte-stable — no existing caller breaks.

string

string

ISO date YYYY-MM-DD (inclusive)

string

ISO date YYYY-MM-DD (inclusive)

ObsOptions = {}

optional source filter + strategy mode + grain

Promise<ObsResult>

ObsResult: per-report ObsRow array + frameSource

ValidationError when station is malformed OR not in the registry (before any fetch — same typed error climate() throws)

DataAvailabilityError when strategy=‘hosted’ (v0.2.x deferral)

DataAvailabilityError when granularity=‘daily’ (not yet ported in TS)

TypeError when strategy or granularity is not in the accepted enum


openMeteoForecasts(station, fromDate, toDate, opts): Promise<OpenMeteoRow[]>

Defined in: packages-ts/weather/src/forecasts/open-meteo.ts:163

Fetch Open-Meteo forecasts for station in [fromDate, toDate].

Phase 20 OM-07. Mirrors Python fetch_open_meteo(...). Default mode: "training" hits Previous Runs API; with issuedAt: "..." dispatches to Single Runs API. mode: "live" hits Live Forecast API with cycle-math fallback issuedAt. mode: "seamless" requires allowLeakage: true (BANNED for training data).

string

string

string

OpenMeteoOptions = {}

Promise<OpenMeteoRow[]>


parseAwcVisibility(vis): null | number

Defined in: packages-ts/weather/src/_parsers/awc.ts:152

Parse AWC visibility — handles all forms documented in the Python parser:

  • numeric (10) → 10
  • “10+” → 10 (trailing plus = “or more”)
  • “1/2” → 0.5
  • “2 1/4” → 2.25
  • “M1/4” → 0.25 (METAR “less than” prefix)
  • bad input / empty / “null” → null

All results are clamped at MAX_VISIBILITY_MILES (99.99).

undefined | null | string | number

null | number


parseCliRecord(record, stationCode): null | ClimateObservation

Defined in: packages-ts/weather/src/_parsers/cli.ts:175

Parse one IEM CLI record into a ClimateObservation.

Returns null if:

  • valid is missing, non-string, or not a real calendar date, OR
  • both high and low end up null after bounds checks.

Mirrors Python parse_cli_record.

CliRawRecord

string

null | ClimateObservation


parseCliResponse(data, stationCode): readonly ClimateObservation[]

Defined in: packages-ts/weather/src/_parsers/cli.ts:235

Parse a full IEM CLI response (post-unwrap) into climate observations, filtering out records where both temps are missing or the date is invalid. Mirrors Python parse_cli_response.

readonly CliRawRecord[]

string

readonly ClimateObservation[]


parseEarningsPayload(payload, options): EarningsRow[]

Defined in: packages-ts/weather/src/_fetchers/earnings.ts:159

Project untrusted hosted-feed JSON to canonical EarningsRows.

Accepts either { rows: [...] } or a bare array. Each row is parsed defensively (no eval): passthrough schema fields are copied by type, and the temporal overlay is derived — eventTime from event_time, knowledgeTime from transcript_available_at (falling back to as_of_time / knowledge_time). A row whose knowledgeTime cannot be parsed to a tz-aware UTC instant is DROPPED (never emitted) — the leakage firewall.

unknown

ParseEarningsPayloadOptions = {}

EarningsRow[]


parseGhcnhPsv(psvBody): readonly Observation[]

Defined in: packages-ts/weather/src/_parsers/ghcnh.ts:347

Parse a GHCNh PSV body string into Observation rows.

Hand-rolled pipe-split — no csv dep. Empty body / header-only → []. Rows that parseGhcnhRow skips are omitted (no null entries).

string

readonly Observation[]


parseGhcnhRow(row): null | Observation

Defined in: packages-ts/weather/src/_parsers/ghcnh.ts:181

Parse one GHCNh PSV row (header→cell dict) into the canonical Observation row. Returns null if the row should be skipped:

  • Station code unresolvable from any Source_Station_ID column
  • DATE missing / malformed / calendar-invalid / out-of-year-range
  • ALL four key vars (temperature, dew_point_temperature, wind_speed, sea_level_pressure) fail Quality_Code

Output dict-key order is preserved verbatim to keep downstream JSON.stringify byte-stable across SDKs.

Readonly<Record<string, string>>

null | Observation


parseIemCsv(csvBody, opts): readonly Observation[]

Defined in: packages-ts/weather/src/_parsers/iem.ts:367

Parse a full IEM CSV body into Observation rows.

  • Lines beginning with # are dropped before the header is consumed (mirror Python filtered = (line for line in f if not line.startswith("#"))).
  • The first non-comment line is the header; subsequent lines are data.
  • Rows that iemToObservation rejects are silently dropped (parser never throws on bad data; only observationTypeOverride validation throws — that’s a programmer-error path).

Returns an empty array for empty / header-only / all-comments input.

string

IemToObservationOptions = {}

readonly Observation[]


projectSatelliteRow(raw, retrievedAt): null | SatelliteRow

Defined in: packages-ts/weather/src/hosted/satellite.ts:139

Project one untrusted wire row into a canonical SatelliteRow.

Reads snake_case wire keys (parity with the Python live schema) and emits camelCase props. source is passed through verbatim (D2 — never re-derived); delivery is forced to "hosted" (this is the hosted path, D-28.2). The leakage overlay (eventTime / knowledgeTime) is derived from the wire event_time / knowledge_time (falling back to scan_start_utc / as_of_time) and normalized to tz-aware UTC — a row that cannot be knowledge-anchored still ships (annotate-never-drop), carrying a null knowledgeTime, matching the Python annotate-never-drop discipline (D5).

unknown

string

null | SatelliteRow


projectStreamRow(event, payload, streamSeq): EarningsStreamRow

Defined in: packages-ts/weather/src/_fetchers/earnings_stream.ts:137

Project an untrusted SSE payload into a canonical EarningsStreamRow. Reads snake_case wire keys (the Python producer’s canonical schema output) and emits camelCase TS row properties. knowledgeTime = the publish wallclock (published_at / knowledge_time), distinct from spokenAt (spoken_at / event_time) — codex P2.

"transcript_segment" | "fact_delta" | "end_of_call" | "resume_incomplete"

unknown

null | number

EarningsStreamRow


requireHostedUrl(value, seamName): string

Defined in: packages-ts/weather/src/hosted/fetch.ts:224

Require a configured hosted base URL seam — a small helper the per-endpoint shims (satellite, hostedStream) share so the “missing WEATHER_HOSTED_URL / EARNINGS_HOSTED_URL” error is uniform and typed (HostedConfigError).

undefined | null | string

string

string

when value is empty/missing. seamName names the env seam in the message (e.g. "WEATHER_HOSTED_URL").


resolveAutoStrategy(fromDate, toDate, source?): ObsStrategy

Defined in: packages-ts/weather/src/obs.ts:58

Resolve auto to the concrete strategy chosen by the smart-router.

Phase 30 30-04 (D-07): "auto" picks the right tactic itself so ordinary callers never type strategy=. A PINNED query (source set) always routes to the source-isolated exact-window path — pinned callers want full single-source coverage for the exact window they asked for, never a year-padded warm-cache span. Unpinned queries keep the window-size heuristic (≤7 days → exact_window, else warm_cache).

string

string

ObsSourceFilter

when set (pinned), forces exact_window regardless of window size. null/undefined (unpinned) uses the size heuristic.

ObsStrategy


satelliteHosted(options): Promise<readonly SatelliteRow[]>

Defined in: packages-ts/weather/src/hosted/satellite.ts:246

Fetch satellite rows from the hosted weather serving /satellite endpoint.

The TS mirror of the Python satellite(delivery="hosted", ...): GETs ${WEATHER_HOSTED_URL}/satellite?... with the MOSTLYRIGHT_API_KEY header and returns rows byte-identical to the Python hosted contract (D-28.2). The source family identity is passed through verbatim; delivery is "hosted".

MV3-safe: fetch + JSON only (via hostedFetchJson). No Node APIs.

SatelliteHostedOptions

Promise<readonly SatelliteRow[]>

when WEATHER_HOSTED_URL / MOSTLYRIGHT_API_KEY / station is missing — surfaced BEFORE any network call.

on a non-2xx or non-JSON response (from hostedFetchJson).


sourceTag(source): LiveSourceTag

Defined in: packages-ts/weather/src/live/sources.ts:107

Map a validated source name to its canonical row-level identity tag.

"iem" | "awc"

LiveSourceTag


stream(station, opts): AsyncGenerator<LiveObservation>

Defined in: packages-ts/weather/src/live/stream.ts:92

Yield fresh observations for station from a SINGLE source on a polite-floor cadence.

The loop:

  1. Validate source + pollSeconds (throws BEFORE first poll).
  2. Poll once.
  3. If the most-recent observation’s observed_at differs from the last one yielded, yield it. Otherwise skip (dedup).
  4. await sleep(pollSeconds).
  5. Loop.

Empty responses (network error, fetcher returned []) DO NOT abort the stream — they’re treated as “nothing fresh yet” and the loop continues after the polite-floor sleep. To get a single-shot failure path, use latest.

string

StreamOptions = {}

AsyncGenerator<LiveObservation>

Error BEFORE the first poll when opts.source is unsupported or opts.pollSeconds is below the polite floor.


validatePollSeconds(pollSeconds, source): number

Defined in: packages-ts/weather/src/live/sources.ts:76

Apply the polite-floor invariant to a caller-supplied cadence.

Caller-supplied cadence. undefined/null → use the floor.

undefined | null | number

A validated source name (call validateSource first).

"iem" | "awc"

number

The cadence to use, in seconds.

Error when pollSeconds is below the polite floor.


validateSource(source): "iem" | "awc"

Defined in: packages-ts/weather/src/live/sources.ts:48

Normalize and validate a source option.

Caller-supplied source string. undefined/null defaults to the first entry in SUPPORTED_SOURCES (AWC). Case-insensitive.

undefined | null | string

"iem" | "awc"

The normalized lowercase source name (one of SUPPORTED_SOURCES).

Error when the source is not in SUPPORTED_SOURCES.


yearlyChunksExclusiveEnd(start, end): readonly readonly [string, string][]

Defined in: packages-ts/weather/src/_fetchers/_iem_chunks.ts:87

Range split into per-calendar-year EXCLUSIVE-end chunks (Jan 1 of next year).

Properties:

  • The first chunk’s start is max(date(start.year, 1, 1), start) — i.e. the caller’s actual start for the first chunk, NOT Jan 1. The current = date(start.year, 1, 1) initialization ensures the loop visits every calendar-year boundary regardless of the caller’s start.
  • Every chunk’s end is date(year+1, 1, 1) — the IEM day2-exclusive convention for “include all of year”.
  • Leap-year safe: advance via date(year+1, 1, 1), NOT +365 days.
  • Reversed range (start > end by lexicographic compare) returns [] without throwing — higher layers iterate the list directly.

Byte-faithful with the Python helper used by iem_asos.download_iem_asos.

string

string

readonly readonly [string, string][]