@aguacerowx/javascript-sdk 0.0.25 → 0.0.27
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/package.json +31 -2
- package/src/AguaceroCore.js +21 -13
- package/src/index.js +7 -1
- package/src/nws/NwsWatchesWarningsOverlay.js +977 -0
- package/src/nws/nwsAlertsFetchSpec.js +93 -0
- package/src/nws/nwsAlertsSupport.js +1337 -0
- package/src/nws/nwsEventColorsDefaults.js +133 -0
- package/src/nws/nwsSdkConstants.js +368 -0
- package/src/nws/nwsWarningCustomizationKey.gen.js +493 -0
- package/src/spawnGridDecodeWorker.js +5 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NWWS `/alerts?hours=` sizing (aguacero-frontend baseline + overlap window parity).
|
|
3
|
+
*
|
|
4
|
+
* Hours follow the **active** observational mode only: NEXRAD → `nexradDurationValue`,
|
|
5
|
+
* MRMS → `mrmsDurationValue`, satellite → `satelliteDurationValue`, otherwise `1` (e.g. model-only).
|
|
6
|
+
* Tier cap uses {@link AguaceroCore} `satelliteTier` — the only subscription-style field on core today
|
|
7
|
+
* (same values as the frontend board tier: basic / enthusiast / professional).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { parseTimelineDurationHours } from '../satellite_support.js';
|
|
11
|
+
|
|
12
|
+
const MAX_ALERT_HISTORY_HOURS = 8760;
|
|
13
|
+
|
|
14
|
+
/** Max option span (hours) per tier from frontend `RADAR_DURATION_CONFIG`. */
|
|
15
|
+
const TIER_MAX_HOURS = {
|
|
16
|
+
professional: 12,
|
|
17
|
+
enthusiast: 4,
|
|
18
|
+
basic: 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {string | undefined} tier
|
|
23
|
+
* @returns {'professional'|'enthusiast'|'basic'}
|
|
24
|
+
*/
|
|
25
|
+
export function normalizeNwsSubscriptionTier(tier) {
|
|
26
|
+
const t = String(tier || 'basic').toLowerCase();
|
|
27
|
+
if (t === 'commercial' || t === 'lifetime' || t === 'partner') return 'professional';
|
|
28
|
+
if (t === 'professional' || t === 'enthusiast' || t === 'basic') return t;
|
|
29
|
+
return 'basic';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string | undefined} tier
|
|
34
|
+
* @returns {number}
|
|
35
|
+
*/
|
|
36
|
+
export function getMaxRadarHistoryHoursForTier(tier) {
|
|
37
|
+
const k = normalizeNwsSubscriptionTier(tier);
|
|
38
|
+
return TIER_MAX_HOURS[k] ?? TIER_MAX_HOURS.basic;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {object | null | undefined} state - {@link AguaceroCore} `state`
|
|
43
|
+
* @returns {number} integer hours in [1, MAX_ALERT_HISTORY_HOURS]
|
|
44
|
+
*/
|
|
45
|
+
export function computeNwsAlertsFetchHoursFromAguaceroState(state) {
|
|
46
|
+
const tierMax = getMaxRadarHistoryHoursForTier(state?.satelliteTier);
|
|
47
|
+
let desired = 1;
|
|
48
|
+
if (state?.isNexrad) {
|
|
49
|
+
desired = parseTimelineDurationHours(state.nexradDurationValue);
|
|
50
|
+
} else if (state?.isMRMS) {
|
|
51
|
+
desired = parseTimelineDurationHours(state.mrmsDurationValue);
|
|
52
|
+
} else if (state?.isSatellite) {
|
|
53
|
+
desired = parseTimelineDurationHours(state.satelliteDurationValue);
|
|
54
|
+
}
|
|
55
|
+
const clamped = Math.min(tierMax, Math.max(1, desired));
|
|
56
|
+
return Math.min(MAX_ALERT_HISTORY_HOURS, Math.floor(clamped));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {number} hours
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
export function nwsAlertsFetchSpecCacheKey(hours) {
|
|
64
|
+
return `h${hours}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Unix window [start, end] for client-side validity overlap (wall-clock end at “now”).
|
|
69
|
+
*
|
|
70
|
+
* @param {number} hours
|
|
71
|
+
* @param {number | null} [anchorSec] - reserved; default now (matches frontend `anchorSec: null`)
|
|
72
|
+
* @returns {{ winStartSec: number; winEndSec: number }}
|
|
73
|
+
*/
|
|
74
|
+
export function nwwsAlertsFetchUnixWindow(hours, anchorSec = null) {
|
|
75
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
76
|
+
const winEndSec = anchorSec ?? nowSec;
|
|
77
|
+
const winStartSec = winEndSec - hours * 3600;
|
|
78
|
+
return { winStartSec, winEndSec };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {string} baseUrl - `/alerts` root (no query)
|
|
83
|
+
* @param {number} hours
|
|
84
|
+
* @returns {string}
|
|
85
|
+
*/
|
|
86
|
+
export function buildNwwsActiveAlertsUrl(baseUrl, hours) {
|
|
87
|
+
const h = Math.max(1, Math.floor(Number(hours) || 1));
|
|
88
|
+
const params = new URLSearchParams();
|
|
89
|
+
params.set('hours', String(h));
|
|
90
|
+
const q = params.toString();
|
|
91
|
+
const base = String(baseUrl || '').replace(/\/$/, '');
|
|
92
|
+
return q ? `${base}?${q}` : base;
|
|
93
|
+
}
|