@mostlyrightmd/weather
Interfaces
Section titled “Interfaces”ClimateObservation
Section titled “ClimateObservation”Properties
Section titled “Properties”high_temp_f
Section titled “high_temp_f”high_temp_f:
null|number
Daily high °F, rounded to int. null when missing or out-of-bounds.
issued_at
Section titled “issued_at”issued_at:
null|string
ISO 8601 UTC issuance time parsed from product[:12], else null.
low_temp_f
Section titled “low_temp_f”low_temp_f:
null|number
Daily low °F, rounded to int. null when missing or out-of-bounds.
observation_date
Section titled “observation_date”observation_date:
string
Local climate day, YYYY-MM-DD.
product_id
Section titled “product_id”product_id:
null|string
Raw NWS product identifier when present.
report_type
Section titled “report_type”report_type:
ReportType
Inferred report type.
report_type_priority
Section titled “report_type_priority”report_type_priority:
number
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
Section titled “source”source:
"iem"
Always "iem" for CLI records.
station_code
Section titled “station_code”station_code:
string
Station code (3-letter NWS or 4-letter ICAO, caller’s choice).
DailyExtremeRow
Section titled “DailyExtremeRow”One station-local day’s rollup.
Field names mirror Python DailyExtreme TypedDict exactly so
cross-language code reads the same way:
date,station,low_f,high_f,mean_f,precip_inlow_coverage(boolean) andobservation_count(int) for debug-friendly gating
Properties
Section titled “Properties”date:
string
Station-local calendar date as YYYY-MM-DD.
high_c
Section titled “high_c”high_c:
null|number
Maximum temperature in °C, or null on low coverage.
high_f
Section titled “high_f”high_f:
null|number
Maximum temperature in °F, or null on low coverage.
low_c:
null|number
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_low_c).
low_coverage
Section titled “low_coverage”low_coverage:
boolean
True when observation_count < 12 (matches Python low-coverage gate).
low_f:
null|number
Minimum temperature in °F, or null on low coverage.
mean_c
Section titled “mean_c”mean_c:
null|number
Mean temperature in °C, or null on low coverage.
mean_f
Section titled “mean_f”mean_f:
null|number
Mean temperature in °F, or null on low coverage.
observation_count
Section titled “observation_count”observation_count:
number
Count of observation rows that contributed to the day.
precip_in
Section titled “precip_in”precip_in:
null|number
Total 1-hour precipitation across the local day, in inches.
source_high
Section titled “source_high”source_high:
null|string
Source identifier of the row that produced tmax (null on low coverage).
source_low
Section titled “source_low”source_low:
null|string
Source identifier of the row that produced tmin (null on low coverage).
station
Section titled “station”station:
string
ICAO station code.
DailyExtremesOptions
Section titled “DailyExtremesOptions”Properties
Section titled “Properties”merge?
Section titled “merge?”
optionalmerge:DailyExtremesMergeMode
Source merge mode; default "live_v1".
signal?
Section titled “signal?”
optionalsignal:AbortSignal
Caller abort signal, propagated to every IEM/AWC fetch (and composed with
each attempt’s retry backoff wait). An abort mid-flight rejects promptly
with the platform AbortError — never reclassified as a transport error.
ForecastNwpOptions
Section titled “ForecastNwpOptions”Optional knobs for forecastNwp.
Properties
Section titled “Properties”cycle?
Section titled “cycle?”
readonlyoptionalcycle:string
Model run datetime — UTC ISO string.
forecastHour?
Section titled “forecastHour?”
readonlyoptionalforecastHour:number
Forecast hour ahead of cycle.
member?
Section titled “member?”
readonlyoptionalmember:string
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+.
IemMosOptions
Section titled “IemMosOptions”Optional knobs for iemMosForecasts.
Properties
Section titled “Properties”fetchFn()?
Section titled “fetchFn()?”
readonlyoptionalfetchFn: (input,init?) =>Promise<Response>(input,init?) =>Promise<Response>
Override the fetch function (used by tests).
Parameters
Section titled “Parameters”URL | RequestInfo
RequestInit
Returns
Section titled “Returns”Promise<Response>
Parameters
Section titled “Parameters”string | URL | Request
RequestInit
Returns
Section titled “Returns”Promise<Response>
model?
Section titled “model?”
readonlyoptionalmodel:IemMosModel
Default "nbe".
signal?
Section titled “signal?”
readonlyoptionalsignal:AbortSignal
Caller abort signal. Propagated to every per-cycle fetch; an abort during
an in-flight request rejects promptly with the platform AbortError.
IemMosRow
Section titled “IemMosRow”One IEM MOS forecast row (PLAN-11). camelCase TS / snake_case Python.
Properties
Section titled “Properties”dewPointC
Section titled “dewPointC”
readonlydewPointC:null|number
2-m dew point in Celsius.
forecastHour
Section titled “forecastHour”
readonlyforecastHour:number
(validAt - issuedAt) in hours.
issuedAt
Section titled “issuedAt”
readonlyissuedAt:string
Model run datetime — UTC ISO string.
readonlymodel:string
UPPERCASE model id (e.g. "NBE").
precipProbability
Section titled “precipProbability”
readonlyprecipProbability:null|number
12-hour probability of precipitation [0, 1].
retrievedAt
Section titled “retrievedAt”
readonlyretrievedAt:string
When the row was fetched — UTC ISO string.
skyCoverPct
Section titled “skyCoverPct”
readonlyskyCoverPct:null|number
Sky cover %; IEM MOS does not expose this — always null.
source
Section titled “source”
readonlysource:IemMosSource
Per-row source identity. Always "iem.archive" for now.
station
Section titled “station”
readonlystation:string
ICAO station code (uppercased).
readonlytempC:null|number
2-m temperature in Celsius (null when MOS field is M / missing).
validAt
Section titled “validAt”
readonlyvalidAt:string
Forecast valid datetime — UTC ISO string.
windDirDeg
Section titled “windDirDeg”
readonlywindDirDeg:null|number
Wind direction in degrees [0, 360).
windSpeedMs
Section titled “windSpeedMs”
readonlywindSpeedMs:null|number
10-m wind speed in m/s.
LatestOptions
Section titled “LatestOptions”Properties
Section titled “Properties”source?
Section titled “source?”
readonlyoptionalsource:null|string
Live source to poll. "awc" (default, fastest) or "iem" (~10-min
delay; useful when AWC is down). Case-insensitive.
Observation
Section titled “Observation”Single observation row, matching specs/observation.json.
Notes on null vs unknown:
- Every field defaults to
nullif 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). sourceis always the string literal"awc"for AWC-sourced rows (the row-level enum is"awc" | "iem" | "ghcnh"; the.live/.archivesuffix is a CATALOG-layer source-id, not a row field).event_time_utcis ISO 8601 UTC withZsuffix.
Properties
Section titled “Properties”altimeter_inhg
Section titled “altimeter_inhg”
readonlyaltimeter_inhg:null|number
dewpoint_c
Section titled “dewpoint_c”
readonlydewpoint_c:null|number
dewpoint_f
Section titled “dewpoint_f”
readonlydewpoint_f:null|number
event_time_utc
Section titled “event_time_utc”
readonlyevent_time_utc:string
observation_type
Section titled “observation_type”
readonlyobservation_type:"METAR"|"SPECI"
peak_wind_dir
Section titled “peak_wind_dir”
readonlypeak_wind_dir:null|number
peak_wind_gust_kt
Section titled “peak_wind_gust_kt”
readonlypeak_wind_gust_kt:null|number
peak_wind_time
Section titled “peak_wind_time”
readonlypeak_wind_time:null|string
precipitation_in_1h
Section titled “precipitation_in_1h”
readonlyprecipitation_in_1h:null|number
qc_field
Section titled “qc_field”
readonlyqc_field:null|number
raw_metar
Section titled “raw_metar”
readonlyraw_metar:null|string
sea_level_pressure_hpa
Section titled “sea_level_pressure_hpa”
readonlysea_level_pressure_hpa:null|number
sky_base_1_ft
Section titled “sky_base_1_ft”
readonlysky_base_1_ft:null|number
sky_base_2_ft
Section titled “sky_base_2_ft”
readonlysky_base_2_ft:null|number
sky_base_3_ft
Section titled “sky_base_3_ft”
readonlysky_base_3_ft:null|number
sky_base_4_ft
Section titled “sky_base_4_ft”
readonlysky_base_4_ft:null|number
sky_cover_1
Section titled “sky_cover_1”
readonlysky_cover_1:null|string
sky_cover_2
Section titled “sky_cover_2”
readonlysky_cover_2:null|string
sky_cover_3
Section titled “sky_cover_3”
readonlysky_cover_3:null|string
sky_cover_4
Section titled “sky_cover_4”
readonlysky_cover_4:null|string
snow_depth_inches
Section titled “snow_depth_inches”
readonlysnow_depth_inches:null|number
source
Section titled “source”
readonlysource:"awc"|"ghcnh"|"iem"
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.
station_code
Section titled “station_code”
readonlystation_code:string
temp_c
Section titled “temp_c”
readonlytemp_c:null|number
temp_f
Section titled “temp_f”
readonlytemp_f:null|number
visibility_miles
Section titled “visibility_miles”
readonlyvisibility_miles:null|number
weather_codes
Section titled “weather_codes”
readonlyweather_codes:null|string
wind_dir_degrees
Section titled “wind_dir_degrees”
readonlywind_dir_degrees:null|number
wind_gust_kt
Section titled “wind_gust_kt”
readonlywind_gust_kt:null|number
wind_speed_kt
Section titled “wind_speed_kt”
readonlywind_speed_kt:null|number
ObsOptions
Section titled “ObsOptions”Properties
Section titled “Properties”signal?
Section titled “signal?”
optionalsignal:AbortSignal
Caller abort signal, propagated to every IEM/AWC fetch (and composed with
each attempt’s retry backoff wait). An abort mid-flight rejects promptly
with the platform AbortError — never reclassified as a transport error.
source?
Section titled “source?”
optionalsource:ObsSourceFilter
Optional source filter. null (default) means all sources merged.
strategy?
Section titled “strategy?”
optionalstrategy:ObsStrategy
Strategy mode; default "auto".
timezone?
Section titled “timezone?”
optionaltimezone:string
IANA timezone override forwarded to the
local_standard_date LST-bucketing machinery (mirrors Python observations(..., timezone=...)). Rarely needed for the canonical station registry (all
covered); used for stations whose tz is not in the registry.
ObsRow
Section titled “ObsRow”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 / …).
Properties
Section titled “Properties”dewpoint_c?
Section titled “dewpoint_c?”
optionaldewpoint_c:null|number
dewpoint_f?
Section titled “dewpoint_f?”
optionaldewpoint_f:null|number
event_time_utc
Section titled “event_time_utc”event_time_utc:
string
local_standard_date?
Section titled “local_standard_date?”
optionallocal_standard_date:string
ISO YYYY-MM-DD string of the local standard day this report belongs to,
computed via localStandardDateFor (never a raw event_time_utc[:10] UTC-day
slice — a pre-midnight-UTC METAR belongs to the PRIOR LST day for
negative-offset US stations). Present on every per-report row with a
parseable event_time_utc; it is the per-report join key the composed
observation-grain dataset uses to LEFT-join daily columns onto each report.
precipitation_mm_1h?
Section titled “precipitation_mm_1h?”
optionalprecipitation_mm_1h:null|number
pressure_inhg?
Section titled “pressure_inhg?”
optionalpressure_inhg:null|number
raw_metar?
Section titled “raw_metar?”
optionalraw_metar:null|string
source
Section titled “source”source:
string
station
Section titled “station”station:
string
temp_c
Section titled “temp_c”temp_c:
null|number
temp_f
Section titled “temp_f”temp_f:
null|number
wind_direction_degrees?
Section titled “wind_direction_degrees?”
optionalwind_direction_degrees:null|number
wind_speed_kts?
Section titled “wind_speed_kts?”
optionalwind_speed_kts:null|number
OpenMeteoOptions
Section titled “OpenMeteoOptions”Optional knobs for openMeteoForecasts.
Properties
Section titled “Properties”allowLeakage?
Section titled “allowLeakage?”
readonlyoptionalallowLeakage:boolean
Required true to invoke mode: "seamless".
fetchFn()?
Section titled “fetchFn()?”
readonlyoptionalfetchFn: (input,init?) =>Promise<Response>(input,init?) =>Promise<Response>
Override the fetch function (used by tests).
Parameters
Section titled “Parameters”URL | RequestInfo
RequestInit
Returns
Section titled “Returns”Promise<Response>
Parameters
Section titled “Parameters”string | URL | Request
RequestInit
Returns
Section titled “Returns”Promise<Response>
issuedAt?
Section titled “issuedAt?”
readonlyoptionalissuedAt:string
Optional ISO cycle for Single Runs API dispatch.
readonlyoptionalmode:OpenMeteoMode
Default "training".
model?
Section titled “model?”
readonlyoptionalmodel:OpenMeteoModel
Default "gfs_global".
signal?
Section titled “signal?”
readonlyoptionalsignal:AbortSignal
Caller abort signal. Propagated to the forecast fetch; an abort during an
in-flight request rejects promptly with the platform AbortError.
OpenMeteoRow
Section titled “OpenMeteoRow”One Open-Meteo forecast row (schema.forecast.station.v1).
Properties
Section titled “Properties”apparentTempC
Section titled “apparentTempC”
readonlyapparentTempC:null|number
capeJkg
Section titled “capeJkg”
readonlycapeJkg:null|number
cloudCoverPct
Section titled “cloudCoverPct”
readonlycloudCoverPct:null|number
dewPointC
Section titled “dewPointC”
readonlydewPointC:null|number
directRadiationWm2
Section titled “directRadiationWm2”
readonlydirectRadiationWm2:null|number
forecastHour
Section titled “forecastHour”
readonlyforecastHour:null|number
(validAt - issuedAt) in hours. null when issuedAt is null.
freezingLevelM
Section titled “freezingLevelM”
readonlyfreezingLevelM:null|number
issuedAt
Section titled “issuedAt”
readonlyissuedAt:null|string
Model run datetime — UTC ISO string. May be null for
source="open_meteo.seamless" rows (cycle unrecoverable by design).
readonlymodel:string
Open-Meteo model key (lowercase, e.g. "gfs_global").
precipitationMm
Section titled “precipitationMm”
readonlyprecipitationMm:null|number
precipProbability
Section titled “precipProbability”
readonlyprecipProbability:null|number
pressureMslHpa
Section titled “pressureMslHpa”
readonlypressureMslHpa:null|number
retrievedAt
Section titled “retrievedAt”
readonlyretrievedAt:string
shortwaveRadiationWm2
Section titled “shortwaveRadiationWm2”
readonlyshortwaveRadiationWm2:null|number
snowDepthM
Section titled “snowDepthM”
readonlysnowDepthM:null|number
source
Section titled “source”
readonlysource:OpenMeteoSource
station
Section titled “station”
readonlystation:string
surfacePressureHpa
Section titled “surfacePressureHpa”
readonlysurfacePressureHpa:null|number
readonlytempC:null|number
validAt
Section titled “validAt”
readonlyvalidAt:string
visibilityM
Section titled “visibilityM”
readonlyvisibilityM:null|number
weatherCode
Section titled “weatherCode”
readonlyweatherCode:null|number
windDirDeg
Section titled “windDirDeg”
readonlywindDirDeg:null|number
windGustsMs
Section titled “windGustsMs”
readonlywindGustsMs:null|number
windSpeedMs
Section titled “windSpeedMs”
readonlywindSpeedMs:null|number
SatelliteHostedOptions
Section titled “SatelliteHostedOptions”Properties
Section titled “Properties”apiKey
Section titled “apiKey”
readonlyapiKey:string
The MOSTLYRIGHT_API_KEY sent as x-api-key. REQUIRED.
fetchImpl?
Section titled “fetchImpl?”
readonlyoptionalfetchImpl:FetchLike
Injectable fetch (tests). Default: the browser/MV3 global.
fromTime
Section titled “fromTime”
readonlyfromTime:string
Event-time window start (ISO-8601).
hostedUrl
Section titled “hostedUrl”
readonlyhostedUrl:string
The weather serving base URL (MOSTLYRIGHT_WEATHER_HOSTED_URL) — the deployed
mr-serving origin. REQUIRED; a missing seam throws HostedConfigError.
In the MV3 extension this is build-injected.
product?
Section titled “product?”
readonlyoptionalproduct:string
Optional product id; omit for the server’s per-source default product.
retrievedAt?
Section titled “retrievedAt?”
readonlyoptionalretrievedAt:string
Retrieval timestamp override (ISO-8601 UTC). Default: now.
satellite
Section titled “satellite”
readonlysatellite:string
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.
signal?
Section titled “signal?”
readonlyoptionalsignal:AbortSignal
Optional AbortSignal for cancellation.
station
Section titled “station”
readonlystation:string| readonlystring[]
Single station or a list (ICAO/NWS codes). At least one is required.
toTime
Section titled “toTime”
readonlytoTime:string
Event-time window end (ISO-8601).
variable?
Section titled “variable?”
readonlyoptionalvariable:string
Optional single-variable filter.
SatelliteRow
Section titled “SatelliteRow”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.
Properties
Section titled “Properties”asOfTime
Section titled “asOfTime”
readonlyasOfTime:null|string
RFC3339-Z knowledge-time string echoed by the server, or null.
delivery
Section titled “delivery”
readonlydelivery:"hosted"
Delivery channel lineage — always "hosted" on this path.
eventTime
Section titled “eventTime”
readonlyeventTime:null|string
Event time (scan start), ISO-8601 UTC, or null.
ingestedAt
Section titled “ingestedAt”
readonlyingestedAt:null|string
knowledgeTime
Section titled “knowledgeTime”
readonlyknowledgeTime:null|string
Knowledge time (leakage anchor), ISO-8601 UTC, or null.
pixelCol
Section titled “pixelCol”
readonlypixelCol:null|number
pixelDataQualityFlag
Section titled “pixelDataQualityFlag”
readonlypixelDataQualityFlag:null|number
pixelRow
Section titled “pixelRow”
readonlypixelRow:null|number
pixelValue
Section titled “pixelValue”
readonlypixelValue:null|number
pressureLevelHpa
Section titled “pressureLevelHpa”
readonlypressureLevelHpa:null|number
product
Section titled “product”
readonlyproduct:string
qcStatus
Section titled “qcStatus”
readonlyqcStatus:string
retrievedAt
Section titled “retrievedAt”
readonlyretrievedAt:string
When the SDK retrieved the row (ISO-8601 UTC).
satellite
Section titled “satellite”
readonlysatellite:string
scanEndUtc
Section titled “scanEndUtc”
readonlyscanEndUtc:null|string
Byte-faithful RFC3339-Z scan-end string, or null.
scanStartUtc
Section titled “scanStartUtc”
readonlyscanStartUtc:null|string
Byte-faithful RFC3339-Z scan-start string (event time), or null.
source
Section titled “source”
readonlysource:string
Satellite family identity — passed through verbatim (D2), never re-derived.
sourceObjectKey
Section titled “sourceObjectKey”
readonlysourceObjectKey:string
station
Section titled “station”
readonlystation:string
stationLat
Section titled “stationLat”
readonlystationLat:null|number
stationLon
Section titled “stationLon”
readonlystationLon:null|number
subsatelliteLongitudeDegrees
Section titled “subsatelliteLongitudeDegrees”
readonlysubsatelliteLongitudeDegrees:null|number
readonlyunits:string
variable
Section titled “variable”
readonlyvariable:string
StreamOptions
Section titled “StreamOptions”Properties
Section titled “Properties”pollSeconds?
Section titled “pollSeconds?”
readonlyoptionalpollSeconds:null|number
Override the polite-floor cadence. Must be >= the per-source floor
(AWC=30, IEM=60). When omitted, uses the floor for the active source.
signal?
Section titled “signal?”
readonlyoptionalsignal:AbortSignal
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.
source?
Section titled “source?”
readonlyoptionalsource:null|string
Live source to poll. "awc" (default) or "iem". Case-insensitive.
Type Aliases
Section titled “Type Aliases”DailyExtremesMergeMode
Section titled “DailyExtremesMergeMode”DailyExtremesMergeMode:
"live_v1"|"awc_only"|"iem_only"
Merge mode controlling which sources contribute observations.
live_v1(default) — IEM ASOS for historical depth + AWC for the recent 168h window. Matches Pythonmerge="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.
IemMosModel
Section titled “IemMosModel”IemMosModel:
"nbe"|"gfs"|"lav"|"met"|"ecm"
IEM MOS model enum (matches Python SUPPORTED_MOS_MODELS).
IemMosSource
Section titled “IemMosSource”IemMosSource:
"iem.archive"|"iem.live"
Canonical source enum (matches Python source column values).
LiveObservation
Section titled “LiveObservation”LiveObservation:
Omit<Observation,"source"> &object
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.
Type declaration
Section titled “Type declaration”source
Section titled “source”
readonlysource:LiveSourceTag
LiveSource
Section titled “LiveSource”LiveSource: typeof
SUPPORTED_SOURCES[number]
Validated source enum derived from SUPPORTED_SOURCES.
LiveSourceTag
Section titled “LiveSourceTag”LiveSourceTag: typeof
SOURCE_IDENTITY_TAGS[LiveSource]
NwpModel
Section titled “NwpModel”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"
NWP model enum — mirror of Python SUPPORTED_NWP_MODELS (24 entries).
ObsFrameSource
Section titled “ObsFrameSource”ObsFrameSource:
"merged.live_v1"|"awc"|"iem"|"ghcnh"
Frame-level source identity — serialized as provenance.source on the
@mostlyrightmd/core!DataResult observations() returns (DX-H4).
Value mirrors Python df.attrs["source"]:
- unpinned (
sourceomitted / null) →"merged.live_v1"(the fused-policy frame tag a single-source/pinned schema MUST loudly reject). - pinned (
sourceset) → the bare pinned source ("awc"/"iem").
ObsSourceFilter
Section titled “ObsSourceFilter”ObsSourceFilter:
"awc"|"iem"|"ghcnh"|null
Source filter — matches Python tw.weather.obs(source=...) _VALID_SOURCES
frozenset {"awc", "iem", "ghcnh"}. null (default) means all sources
merged.
fix-: 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
Section titled “ObsStrategy”ObsStrategy:
"auto"|"exact_window"|"warm_cache"|"hosted"
Strategy enum — matches Python verbatim.
OpenMeteoMode
Section titled “OpenMeteoMode”OpenMeteoMode:
"training"|"live"|"seamless"
Open-Meteo dispatch mode for openMeteoForecasts.
OpenMeteoModel
Section titled “OpenMeteoModel”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"
The 36 Open-Meteo forecast models in scope.
OpenMeteoSource
Section titled “OpenMeteoSource”OpenMeteoSource:
"open_meteo.previous_runs"|"open_meteo.single_run"|"open_meteo.live"|"open_meteo.seamless"
Open-Meteo source-identity enum (per-endpoint discrimination).
ReportType
Section titled “ReportType”ReportType:
"final"|"ncei_final"|"correction"|"preliminary"|"estimated"
SatelliteSourceIdentity
Section titled “SatelliteSourceIdentity”SatelliteSourceIdentity: typeof
SATELLITE_SOURCE_IDENTITIES[number]
Variables
Section titled “Variables”HIGH_TEMP_MAX_F
Section titled “HIGH_TEMP_MAX_F”
constHIGH_TEMP_MAX_F:150=150
HIGH_TEMP_MIN_F
Section titled “HIGH_TEMP_MIN_F”
constHIGH_TEMP_MIN_F:-60=-60
Climate temp bounds from specs/climate.json. Inclusive.
LOW_TEMP_MAX_F
Section titled “LOW_TEMP_MAX_F”
constLOW_TEMP_MAX_F:130=130
LOW_TEMP_MIN_F
Section titled “LOW_TEMP_MIN_F”
constLOW_TEMP_MIN_F:-80=-80
OPEN_METEO_MODELS
Section titled “OPEN_METEO_MODELS”
constOPEN_METEO_MODELS:ReadonlySet<OpenMeteoModel>
The canonical 36-model set (set-equality lock).
POLITE_FLOORS_S
Section titled “POLITE_FLOORS_S”
constPOLITE_FLOORS_S:Readonly<Record<LiveSource,number>>
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.
SATELLITE_SOURCE_IDENTITIES
Section titled “SATELLITE_SOURCE_IDENTITIES”
constSATELLITE_SOURCE_IDENTITIES: readonly ["noaa_goes","jma_himawari","noaa_viirs","eumetsat_meteosat"]
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).
SOURCE_IDENTITY_TAGS
Section titled “SOURCE_IDENTITY_TAGS”
constSOURCE_IDENTITY_TAGS:object
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.
Type declaration
Section titled “Type declaration”
readonlyawc:"awc.live"="awc.live"
readonlyiem:"iem.live"="iem.live"
SUPPORTED_SOURCES
Section titled “SUPPORTED_SOURCES”
constSUPPORTED_SOURCES: readonly ["awc","iem"]
Canonical ordered tuple of supported sources. Order matters — keep AWC first.
version
Section titled “version”
constversion:"1.9.9"="1.9.9"
Public package version; kept in lockstep with package.json.
Functions
Section titled “Functions”dailyExtremes()
Section titled “dailyExtremes()”dailyExtremes(
station,fromDate,toDate,opts):Promise<DataResult<DailyExtremeRow>>
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 (
invariant); other stations get 0.1-precision values.
Parameters
Section titled “Parameters”station
Section titled “station”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).
fromDate
Section titled “fromDate”string
ISO date YYYY-MM-DD (inclusive, station-local)
toDate
Section titled “toDate”string
ISO date YYYY-MM-DD (inclusive, station-local)
DailyExtremesOptions = {}
optional merge mode (default "live_v1")
Returns
Section titled “Returns”Promise<DataResult<DailyExtremeRow>>
array of DailyExtremeRow, one per station-local day
Throws
Section titled “Throws”Error if station is not in the STATIONS registry
forecastNwp()
Section titled “forecastNwp()”forecastNwp(
station,model,_opts):Promise<never>
Fetch a gridded NWP forecast — v1.x stub, deferred to v2.0+.
Parameters
Section titled “Parameters”station
Section titled “station”string
ForecastNwpOptions = {}
Returns
Section titled “Returns”Promise<never>
Remarks
Section titled “Remarks”⚠️ 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).
Throws
Section titled “Throws”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.
iemMosForecasts()
Section titled “iemMosForecasts()”iemMosForecasts(
station,fromDate,toDate,opts):Promise<DataResult<IemMosRow>>
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 [].
Parameters
Section titled “Parameters”station
Section titled “station”string
fromDate
Section titled “fromDate”string
toDate
Section titled “toDate”string
IemMosOptions = {}
Returns
Section titled “Returns”Promise<DataResult<IemMosRow>>
Throws
Section titled “Throws”Error if model is not in SUPPORTED_MODELS.
isLiveSource()
Section titled “isLiveSource()”isLiveSource(
s): s is “awc” | “iem”
Type guard: narrow a string to LiveSource.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”s is “awc” | “iem”
latest()
Section titled “latest()”latest(
station,opts):Promise<LiveObservation>
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.
Parameters
Section titled “Parameters”station
Section titled “station”string
ICAO ("KNYC") or 3-letter US ID ("NYC"). Case-insensitive.
LatestOptions = {}
Optional { source }.
Returns
Section titled “Returns”Promise<LiveObservation>
Throws
Section titled “Throws”Error when opts.source is unknown.
Throws
Section titled “Throws”NoLiveDataError when the upstream returned no observations
for the station — payload carries the resolved station and live
source tag for branching.
observations()
Section titled “observations()”observations(
rawStation,fromDate,toDate,opts):Promise<DataResult<ObsRow>>
Fetch the merged per-report observations for a station’s window.
Mirrors Python mostlyright.weather.observations(station, from_date, to_date, source=None, strategy='auto') — per-report rows only. The strategy enum
selects between the smart-router’s three concrete fetch paths.
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"]. Every row carries a local_standard_date.
Parameters
Section titled “Parameters”rawStation
Section titled “rawStation”string
ICAO code (e.g. “KNYC”) OR 3-letter NWS code (e.g. “NYC”). Resolved through the station registry: IEM ASOS is fetched by the NWS code, AWC by the ICAO — so observations(“KNYC”) == observations(“NYC”).
fromDate
Section titled “fromDate”string
ISO date YYYY-MM-DD (inclusive)
toDate
Section titled “toDate”string
ISO date YYYY-MM-DD (inclusive)
ObsOptions = {}
optional source filter + strategy mode
Returns
Section titled “Returns”Promise<DataResult<ObsRow>>
ObsResult: per-report ObsRow array + frameSource
Throws
Section titled “Throws”ValidationError when station is malformed OR not in the registry (before any fetch — same typed error climate() throws)
Throws
Section titled “Throws”DataAvailabilityError when strategy=‘hosted’ (v0.2.x deferral)
Throws
Section titled “Throws”TypeError when strategy is not in the accepted enum
openMeteoForecasts()
Section titled “openMeteoForecasts()”openMeteoForecasts(
station,fromDate,toDate,opts):Promise<DataResult<OpenMeteoRow>>
Fetch Open-Meteo forecasts for station in [fromDate, toDate].
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).
Parameters
Section titled “Parameters”station
Section titled “station”string
fromDate
Section titled “fromDate”string
toDate
Section titled “toDate”string
OpenMeteoOptions = {}
Returns
Section titled “Returns”Promise<DataResult<OpenMeteoRow>>
projectSatelliteRow()
Section titled “projectSatelliteRow()”projectSatelliteRow(
raw,retrievedAt):null|SatelliteRow
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,). The
leakage overlay (eventTime / knowledgeTime) is derived from the wire
event_time_utc / 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).
Parameters
Section titled “Parameters”unknown
retrievedAt
Section titled “retrievedAt”string
Returns
Section titled “Returns”null | SatelliteRow
satelliteHosted()
Section titled “satelliteHosted()”satelliteHosted(
options):Promise<readonlySatelliteRow[]>
Fetch satellite rows from the hosted weather serving /satellite endpoint.
The TS mirror of the Python satellite(delivery="hosted", ...): GETs
${MOSTLYRIGHT_WEATHER_HOSTED_URL}/satellite?... with the MOSTLYRIGHT_API_KEY header and
returns rows byte-identical to the Python hosted contract. The
source family identity is passed through verbatim; delivery is "hosted".
MV3-safe: fetch + JSON only (via hostedFetchJson). No Node APIs.
Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”Promise<readonly SatelliteRow[]>
Throws
Section titled “Throws”when MOSTLYRIGHT_WEATHER_HOSTED_URL / MOSTLYRIGHT_API_KEY /
station is missing — surfaced BEFORE any network call.
Throws
Section titled “Throws”on a non-2xx or non-JSON response (from
hostedFetchJson).
sourceTag()
Section titled “sourceTag()”sourceTag(
source):LiveSourceTag
Map a validated source name to its canonical row-level identity tag.
Parameters
Section titled “Parameters”source
Section titled “source”"awc" | "iem"
Returns
Section titled “Returns”stream()
Section titled “stream()”stream(
station,opts):AsyncGenerator<LiveObservation>
Yield fresh observations for station from a SINGLE source on a
polite-floor cadence.
The loop:
- Validate
source+pollSeconds(throws BEFORE first poll). - Poll once.
- If the most-recent observation’s
event_time_utcdiffers from the last one yielded, yield it. Otherwise skip (dedup). await sleep(pollSeconds).- 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.
Parameters
Section titled “Parameters”station
Section titled “station”string
StreamOptions = {}
Returns
Section titled “Returns”AsyncGenerator<LiveObservation>
Throws
Section titled “Throws”Error BEFORE the first poll when opts.source is unsupported
or opts.pollSeconds is below the polite floor.
validatePollSeconds()
Section titled “validatePollSeconds()”validatePollSeconds(
pollSeconds,source):number
Apply the polite-floor invariant to a caller-supplied cadence.
Parameters
Section titled “Parameters”pollSeconds
Section titled “pollSeconds”Caller-supplied cadence. undefined/null → use the floor.
undefined | null | number
source
Section titled “source”A validated source name (call validateSource first).
"awc" | "iem"
Returns
Section titled “Returns”number
The cadence to use, in seconds.
Throws
Section titled “Throws”Error when pollSeconds is below the polite floor.
validateSource()
Section titled “validateSource()”validateSource(
source):"awc"|"iem"
Normalize and validate a source option.
Parameters
Section titled “Parameters”source
Section titled “source”Caller-supplied source string. undefined/null defaults
to the first entry in SUPPORTED_SOURCES (AWC). Case-insensitive.
undefined | null | string
Returns
Section titled “Returns”"awc" | "iem"
The normalized lowercase source name (one of SUPPORTED_SOURCES).
Throws
Section titled “Throws”Error when the source is not in SUPPORTED_SOURCES.