mostlyright 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  MODE2_SOURCES: () => MODE2_SOURCES,
35
35
  NoLiveDataError: () => import_core4.NoLiveDataError,
36
36
  POLITE_FLOORS_S: () => import_weather4.POLITE_FLOORS_S,
37
+ Preprocessing: () => Preprocessing,
37
38
  SELECTOR_NAMES: () => SELECTOR_NAMES,
38
39
  SOURCE_ALIASES: () => SOURCE_ALIASES,
39
40
  SOURCE_IDENTITY_TAGS: () => import_weather4.SOURCE_IDENTITY_TAGS,
@@ -42,6 +43,7 @@ __export(index_exports, {
42
43
  assertSourceIdentity: () => assertSourceIdentity,
43
44
  buildOverrideWarning: () => buildOverrideWarning,
44
45
  core: () => core,
46
+ dailyExtremes: () => import_weather5.dailyExtremes,
45
47
  discover: () => discover,
46
48
  helloCore: () => import_core3.helloCore,
47
49
  helloMarkets: () => import_markets2.helloMarkets,
@@ -50,6 +52,8 @@ __export(index_exports, {
50
52
  isMode2Source: () => isMode2Source,
51
53
  latest: () => import_weather4.latest,
52
54
  markets: () => markets,
55
+ obs: () => import_weather6.obs,
56
+ preprocessing: () => preprocessing,
53
57
  research: () => research,
54
58
  researchBySource: () => researchBySource,
55
59
  resolveCity: () => resolveCity,
@@ -76,6 +80,63 @@ var import_cache = require("@mostlyrightmd/core/internal/cache");
76
80
  var import_merge = require("@mostlyrightmd/core/internal/merge");
77
81
  var import_pairs = require("@mostlyrightmd/core/internal/pairs");
78
82
  var import_weather = require("@mostlyrightmd/weather");
83
+
84
+ // src/research.types.ts
85
+ var KNOWN_RESEARCH_OPTION_KEYS = /* @__PURE__ */ new Set([
86
+ // Pre-Phase-21 fetcher controls.
87
+ "signal",
88
+ "awcHours",
89
+ "iemPolitenessMs",
90
+ "ghcnhPolitenessMs",
91
+ "cliPolitenessMs",
92
+ "now",
93
+ "cache",
94
+ // Pre-Phase-21 selectors.
95
+ "city",
96
+ "contract",
97
+ "contracts",
98
+ "stationOverride",
99
+ "sources",
100
+ "source",
101
+ "includeTrades",
102
+ "onWarning",
103
+ // Phase 21 21-01: Python-parity composable kwargs.
104
+ "include_forecast",
105
+ "forecast_model",
106
+ "forecast_models",
107
+ "qc",
108
+ "tz_override",
109
+ "backend",
110
+ "return_type"
111
+ ]);
112
+ function validateResearchKwargs(opts) {
113
+ const present = (v) => v !== void 0 && v !== null;
114
+ for (const key of Object.keys(opts)) {
115
+ if (!KNOWN_RESEARCH_OPTION_KEYS.has(key)) {
116
+ throw new TypeError(
117
+ `research(): unknown option key ${JSON.stringify(key)}. Valid keys: ${[...KNOWN_RESEARCH_OPTION_KEYS].sort().join(", ")}`
118
+ );
119
+ }
120
+ }
121
+ if (present(opts.sources) && present(opts.source)) {
122
+ throw new TypeError(
123
+ "research(): sources= and source= are mutually exclusive \u2014 use `sources=` for the LIVE_V1 multi-source selector or `source=` for a single-source query, not both"
124
+ );
125
+ }
126
+ if (present(opts.forecast_model) && present(opts.forecast_models)) {
127
+ throw new TypeError(
128
+ "research(): forecast_model= and forecast_models= are mutually exclusive \u2014 use `forecast_models=` for multi-model fan-out or `forecast_model=` for a single model, not both"
129
+ );
130
+ }
131
+ const wantsForecast = present(opts.forecast_model) || present(opts.forecast_models);
132
+ if (wantsForecast && opts.include_forecast !== true) {
133
+ throw new TypeError(
134
+ "research(): forecast_model=/forecast_models= require include_forecast=true; the model filter is otherwise silently ignored"
135
+ );
136
+ }
137
+ }
138
+
139
+ // src/research.ts
79
140
  var AWC_MAX_HOURS = 168;
80
141
  async function resolveCache(opts) {
81
142
  if (opts.cache === null) return null;
@@ -342,9 +403,9 @@ async function fetchIemAsosWithCache(stationCode, _fromYear, _extendedToYear, fr
342
403
  }
343
404
  }
344
405
  }
345
- for (const obs of monthRows) {
346
- const obsDate = obs.observed_at.slice(0, 10);
347
- if (obsDate >= fromDate && obsDate <= extendedTo) acc.push(obs);
406
+ for (const obs2 of monthRows) {
407
+ const obsDate = obs2.observed_at.slice(0, 10);
408
+ if (obsDate >= fromDate && obsDate <= extendedTo) acc.push(obs2);
348
409
  }
349
410
  }
350
411
  return acc;
@@ -415,14 +476,22 @@ async function fetchGhcnhWithCache(stationCode, ghcnhId, fromDate, extendedTo, o
415
476
  }
416
477
  }
417
478
  }
418
- for (const obs of monthRows) {
419
- const obsDate = obs.observed_at.slice(0, 10);
420
- if (obsDate >= fromDate && obsDate <= extendedTo) acc.push(obs);
479
+ for (const obs2 of monthRows) {
480
+ const obsDate = obs2.observed_at.slice(0, 10);
481
+ if (obsDate >= fromDate && obsDate <= extendedTo) acc.push(obs2);
421
482
  }
422
483
  }
423
484
  return acc;
424
485
  }
425
486
  async function research(station, fromDate, toDate, opts = {}) {
487
+ validateResearchKwargs(opts);
488
+ if (opts.backend === "polars") {
489
+ throw new import_core.DataAvailabilityError({
490
+ reason: "model_unavailable",
491
+ hint: 'polars backend not available in TypeScript SDK; use Python (mostlyrightmd) for backend="polars". TS returns plain object arrays.',
492
+ source: "research.backend"
493
+ });
494
+ }
426
495
  const hasCity = typeof opts.city === "string" && opts.city.length > 0;
427
496
  const hasContract = typeof opts.contract === "string" && opts.contract.length > 0;
428
497
  const hasContracts = Array.isArray(opts.contracts) && opts.contracts.length > 0;
@@ -498,8 +567,8 @@ async function research(station, fromDate, toDate, opts = {}) {
498
567
  if (opts.signal !== void 0) awcOpts.signal = opts.signal;
499
568
  const awcRaw = await (0, import_weather.fetchAwcMetars)([resolved.icao], awcOpts);
500
569
  for (const m of awcRaw) {
501
- const obs = (0, import_weather.awcToObservation)(m);
502
- if (obs !== null) awcRows.push(obs);
570
+ const obs2 = (0, import_weather.awcToObservation)(m);
571
+ if (obs2 !== null) awcRows.push(obs2);
503
572
  }
504
573
  }
505
574
  const iemRows = await fetchIemAsosWithCache(
@@ -530,8 +599,8 @@ async function research(station, fromDate, toDate, opts = {}) {
530
599
  const observationsByDate = {};
531
600
  const dateLo = dates[0] ?? "";
532
601
  const dateHi = dates[dates.length - 1] ?? "";
533
- for (const obs of merged) {
534
- const settleDate = observedSettlementDate(obs.observed_at, resolved.code);
602
+ for (const obs2 of merged) {
603
+ const settleDate = observedSettlementDate(obs2.observed_at, resolved.code);
535
604
  if (settleDate === null) continue;
536
605
  if (settleDate < dateLo || settleDate > dateHi) continue;
537
606
  let bucket = observationsByDate[settleDate];
@@ -539,7 +608,7 @@ async function research(station, fromDate, toDate, opts = {}) {
539
608
  bucket = [];
540
609
  observationsByDate[settleDate] = bucket;
541
610
  }
542
- bucket.push(obs);
611
+ bucket.push(obs2);
543
612
  }
544
613
  const climateByDate = {};
545
614
  for (const cli of mergedClimate) {
@@ -675,8 +744,8 @@ async function researchBySource(station, source, fromDate, toDate, opts = {}) {
675
744
  const raw = await (0, import_weather2.fetchAwcMetars)([resolved.icao], awcOpts);
676
745
  const parsed = [];
677
746
  for (const m of raw) {
678
- const obs = (0, import_weather2.awcToObservation)(m);
679
- if (obs !== null) parsed.push(obs);
747
+ const obs2 = (0, import_weather2.awcToObservation)(m);
748
+ if (obs2 !== null) parsed.push(obs2);
680
749
  }
681
750
  rows = parsed.filter((r) => {
682
751
  const d = r.observed_at.slice(0, 10);
@@ -929,6 +998,10 @@ function discover(args) {
929
998
  // src/index.ts
930
999
  var import_weather4 = require("@mostlyrightmd/weather");
931
1000
  var import_core4 = require("@mostlyrightmd/core");
1001
+ var import_weather5 = require("@mostlyrightmd/weather");
1002
+ var import_weather6 = require("@mostlyrightmd/weather");
1003
+ var preprocessing = __toESM(require("@mostlyrightmd/core/preprocessing"), 1);
1004
+ var Preprocessing = preprocessing;
932
1005
  var version = "0.0.0";
933
1006
  // Annotate the CommonJS export names for ESM import in node:
934
1007
  0 && (module.exports = {
@@ -936,6 +1009,7 @@ var version = "0.0.0";
936
1009
  MODE2_SOURCES,
937
1010
  NoLiveDataError,
938
1011
  POLITE_FLOORS_S,
1012
+ Preprocessing,
939
1013
  SELECTOR_NAMES,
940
1014
  SOURCE_ALIASES,
941
1015
  SOURCE_IDENTITY_TAGS,
@@ -944,6 +1018,7 @@ var version = "0.0.0";
944
1018
  assertSourceIdentity,
945
1019
  buildOverrideWarning,
946
1020
  core,
1021
+ dailyExtremes,
947
1022
  discover,
948
1023
  helloCore,
949
1024
  helloMarkets,
@@ -952,6 +1027,8 @@ var version = "0.0.0";
952
1027
  isMode2Source,
953
1028
  latest,
954
1029
  markets,
1030
+ obs,
1031
+ preprocessing,
955
1032
  research,
956
1033
  researchBySource,
957
1034
  resolveCity,