@meri-imperiumi/signalk-passage-briefing 0.8.1 → 0.9.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/CHANGELOG.md +14 -0
- package/README.md +3 -1
- package/SPEC.md +9 -2
- package/package.json +4 -4
- package/plugin/celestial-ephemeris.js +407 -164
- package/plugin/celestial-source.js +67 -1
- package/plugin/index.js +145 -0
- package/plugin/launch-source.js +374 -0
- package/plugin/reentry-source.js +743 -0
- package/public/components/meteors.mjs +224 -0
- package/public/components/models.mjs +43 -0
- package/public/components/passage-outlook.js +40 -0
- package/public/route-sim.mjs +84 -1
- package/public/worker.js +3 -2
- package/tests/celestial-ephemeris.test.js +171 -8
- package/tests/fixtures/cluster-26410-omm.json +44 -0
- package/tests/fixtures/cluster-26464-omm.json +254 -0
- package/tests/fixtures/ll2-upcoming.json +213 -0
- package/tests/fixtures/tip-messages.json +50 -0
- package/tests/launch-source.test.js +178 -0
- package/tests/reentry-source.test.js +340 -0
- package/tests/route-sim.test.js +76 -0
- package/tests/webapp.test.js +120 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.0] - 2026-10-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- The header always names when the served briefing was made: a quiet `Compiled MM-DD HH:MM` pill next to the connectivity and ship's-time pills, stamped from the payload's `fetchedAt` in ship's time on every load (route and here modes alike, any age — the stale-age banner stays the alarm past 24 h, this is the fact next to it). A briefing with no fetch time hides the pill rather than inventing a stamp; the label re-renders when the vessel's timezone arrives.
|
|
9
|
+
- The header names when the next briefing is scheduled: a quiet `Next MM-DD HH:MM` pill beside the Compiled stamp, showing the state machine's next cron window in ship's time (from `/api/status`, fetched with each briefing load). It hides when the plugin serves none — offline, or no cron scheduled — the same hide-rather-than-invent rule the compile stamp follows, and a hover title notes that a manual update can land earlier.
|
|
10
|
+
- Eclipse and moon-phase sky events (work doc #35): the ephemeris now emits discrete moon phase instants (`moonPhase` notes — "New Moon — darkest skies of the passage", "Full Moon — moonlit night watches") and visible eclipses with almanac's built-in observer visibility — lunar eclipses gated on the Moon up at peak, the Sun below the civil twilight line and the cloud gate; solar eclipses on the Sun above the horizon and the cloud gate. Timeline and here-view sky cards carry them like every other event; nothing new is fetched, all local computation. Like every computed-on-board item they carry no provenance record (work doc #31: absence never implies external authority) — pinned by a regression test so the weather provenance chain never leaks onto sky rows.
|
|
11
|
+
- Reentry watch and visible launches (work doc #36): the briefing now answers "could we see that from here?" for the two rarest sky events. Predicted satellite reentries come from Space-Track's TIP messages (the only machine-readable decay forecast; a free account configured once in the plugin, degrading to off without it), refined by CelesTrak element sets and propagated on board with the same SGP4 propagator as the station passes — the visible-event gate models both regimes the Cluster II SAMBA/TANGO deorbits taught us about: fireball at night out to the geometric horizon of the burn altitude (~1000 km), sunlit smoke streak by day readable only close, everything else correctly silent (the backtest that proved the Aitutaki→Niue crew could never have seen those two is now a permanent fixture test). Visible rocket launches come from Launch Library 2 (no account) and fire only for the classic twilight geometry — pad within ~650 nm and the observer in twilight while the vehicle climbs into sunlight — with the bearing to the pad and an honest windows-slip caveat. Both sources follow the house fetch rules: online-window fetches, data-directory caching (TIP 12 h, launch schedule 6 h, stale cache still answers offline), per-source status in the registry with the unconfigured reentry source recorded as absent, and every failure degrading to no events.
|
|
12
|
+
- Eye height above the water as plugin configuration (`celestial_eye_height_m`, default 0): sunrise, sunset and moonrise/set stamps in `celestialNights` — the timeline's night rows and the conditions-here sky line — correct for the dip of the vessel's raised horizon (a couple of minutes from cockpit height). Twilight lines are altitude angles, not horizon crossings, so they stay put.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Meteor showers are evaluated per night, not per peak instant (work doc #37): each shower's nominal peak is judged against the nights bracketing it — the peak night plus its neighbors, since real maxima drift ±1 night — at each night's nautical-dusk anchor, with the radiant altitude checked at the **forecasted position of that night** from the simulated track. A shower whose catalog peak hour lands in local daytime now fires for the dark nights around it instead of vanishing (the Eta Aquariids from New Zealand: 14:00 peak hour, radiant near zenith, moon dark — previously unreportable); descriptions word the bracket nights honestly ("climbing toward the peak" / "just past peak") so no night claims a maximum its darkness never held. The evaluation lives in a shared dependency-free module (`public/components/meteors.mjs`) run where the track lives — the simulation worker computes the route timeline's meteor nights from the track exactly like the sail changes, while here-mode payloads keep them from the server at the vessel position; route payloads no longer carry fixed-position `meteor` entries, so nothing double-reports. The static annual calendar stays (IMO publishes tables, not APIs) but moves into the shared module with its thresholds.
|
|
16
|
+
- The test runner no longer uses `--test-force-exit`: the flag was intermittently killing suites whose subtests register on timers, undercounting the run while everything passed. Without it the whole suite exits cleanly and the count is stable.
|
|
17
|
+
- The ephemeris engine is `@openwaters/almanac` (MIT, the maintained TypeScript port of astronomy-engine at a pinned commit, checked against JPL/USNO/Espenak fixtures over 1950–2100), replacing astronomy-engine — same math lineage and accuracy class, 21.9 KB vs 44 KB, and the twilight chain collapses from three chained searches to window event lists. Rise/set stamps shift by seconds (almanac uses the Sun's true semidiameter instead of a fixed −0.833°); everything else stays behaviorally identical. The npm package is ESM-only, loaded through `require(esm)` — the minimum Node moves to 22.12.0.
|
|
18
|
+
|
|
5
19
|
## [0.8.1] - 2026-10-08
|
|
6
20
|
|
|
7
21
|
### Added
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ The Open-Meteo entries below are the fallback weather source: used when no Weath
|
|
|
41
41
|
- [Open-Meteo Forecast API](https://open-meteo.com/en/docs) — surface wind, gusts, MSL pressure, CAPE and the pressure-layer fields behind the K-index (best-match model)
|
|
42
42
|
- [NOAA SWPC planetary K-index forecast](https://services.swpc.noaa.gov/products/noaa-planetary-k-index-forecast.json) — geomagnetic activity behind the aurora advisories
|
|
43
43
|
- [JPL SBDB query API](https://ssd-api.jpl.nasa.gov/doc/sbdb_query.html) — comet brightness parameters (M1/K1) behind the Sky Notes comets
|
|
44
|
-
- [CelesTrak](https://celestrak.org/NORAD/elements/gp.php?GROUP=stations&FORMAT=tle) — two-line elements for the crewed stations (ISS, Tiangong); bright satellite passes are propagated locally from the fetched TLEs with SGP4, gated to nautical night, clear sky and a 15° haze line
|
|
44
|
+
- [CelesTrak](https://celestrak.org/NORAD/elements/gp.php?GROUP=stations&FORMAT=tle) — two-line elements for the crewed stations (ISS, Tiangong); bright satellite passes are propagated locally from the fetched TLEs with SGP4, gated to nautical night, clear sky and a 15° haze line. The same service's per-catalog queries (`gp.php?CATNR=…`) supply the current elements of decaying satellites named by Space-Track's reentry predictions
|
|
45
45
|
- [NOAA TGFTP radiofax tree](https://tgftp.nws.noaa.gov/fax/) and the [BoM difacs charts](http://www.bom.gov.au/difacs/) — synoptic surface-analysis charts per METAREA zone (work doc #11), per the schedule in [otherfax.txt](https://tgftp.nws.noaa.gov/fax/otherfax.txt)
|
|
46
46
|
- [UKHO Admiralty MSI API](https://msi.admiralty.co.uk/) — structured NAVAREA navigational warnings for the resolved zone; the third rung of the GMDSS bulletin fetch ladder (TGFTP raw text, WMO GMDSS portal, then UKHO MSI JSON) and also accepted verbatim as a `bulletin_urls` source
|
|
47
47
|
- [GDACS RSS](https://www.gdacs.org/xml/rss.xml) — EU JRC global disaster alerts (earthquakes, tropical cyclones, floods, volcanic activity), filtered route-relative by alert level and corridor distance: they ride the unified passage timeline and publish as georeferenced chart notes (work doc #22)
|
|
@@ -49,6 +49,8 @@ The Open-Meteo entries below are the fallback weather source: used when no Weath
|
|
|
49
49
|
- NOAA TGFTP (`tgftp.nws.noaa.gov`) — raw METAREA bulletin text for the resolved GMDSS zone's station (e.g. `FQPS01 NFFN` for XIV)
|
|
50
50
|
- WMO GMDSS portal (`weather.gmdss.org`) — per-zone bulletin pages, fallback when the TGFTP station is not configured
|
|
51
51
|
- api.weather.gov product API — US High Seas Forecast texts (default `bulletin_urls`: HSF NP/EP1/EP2); extra sources can be added via the `bulletin_urls` configuration (plain text or api.weather.gov product URLs; UKHO MSI JSON works too)
|
|
52
|
+
- [Space-Track](https://www.space-track.org) — TIP (Trajectory Impact Prediction) messages, the only machine-readable source of satellite reentry predictions; needs a free account configured in the plugin, without which the reentry watch stays off. The predicted decay is refined on board with the object's CelesTrak elements and the vessel-visible geometry (fireball at night, sunlit smoke streak by day) computed from the propagator and the sky, not taken from the message
|
|
53
|
+
- [Launch Library 2](https://thespacedevs.com/llapi) — upcoming rocket launches with pad coordinates (no account); the briefing names only launches whose twilight geometry would make the plume visible from the vessel's position
|
|
52
54
|
|
|
53
55
|
All external fetches are online-gated and cached to the plugin data directory, so the last payloads survive the offline hours.
|
|
54
56
|
|
package/SPEC.md
CHANGED
|
@@ -197,7 +197,7 @@ interface UnifiedWeatherPayload {
|
|
|
197
197
|
bulletinText: string;
|
|
198
198
|
};
|
|
199
199
|
spaceEvents?: {
|
|
200
|
-
kind: string; // 'aurora' | 'comet' | 'conjunction' | 'opposition' | 'meteor'
|
|
200
|
+
kind: string; // 'aurora' | 'comet' | 'conjunction' | 'opposition' | 'meteor' | 'moonPhase' | 'lunarEclipse' | 'solarEclipse' | 'satellite' | 'reentry' | 'launch'
|
|
201
201
|
timestamp: string; // ISO timestamp
|
|
202
202
|
tactical: boolean; // 24h dashboard banner vs strategic sky note
|
|
203
203
|
description: string;
|
|
@@ -564,7 +564,14 @@ function filterExceptions(simulationResult) {
|
|
|
564
564
|
totalMotorHours: simulationResult.motoringHours,
|
|
565
565
|
totalFuelGal: simulationResult.fuelConsumptionGal,
|
|
566
566
|
macroSeaAnomalies: simulationResult.seaStateAnomalies.filter(a => a.steepnessRatio < 3.28),
|
|
567
|
-
convectiveWarnings: simulationResult.upperAirAnomalies.filter(u => u.cape > 1000 || u.kIndex > 28)
|
|
567
|
+
convectiveWarnings: simulationResult.upperAirAnomalies.filter(u => u.cape > 1000 || u.kIndex > 28),
|
|
568
|
+
// Meteor-shower nights evaluated along the track (work doc #37):
|
|
569
|
+
// per (shower, night) spaceEvents gated at the night's nautical-dusk
|
|
570
|
+
// anchor, the radiant checked at the track's forecasted position;
|
|
571
|
+
// route payloads carry no fixed-position `meteor` spaceEvents —
|
|
572
|
+
// these are the timeline's meteors. Here-mode payloads keep them
|
|
573
|
+
// in `spaceEvents` (single position, no track)
|
|
574
|
+
meteorEvents: simulationResult.meteorEvents
|
|
568
575
|
}
|
|
569
576
|
};
|
|
570
577
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meri-imperiumi/signalk-passage-briefing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Offshore passage daily briefing webapp for Signal K",
|
|
5
5
|
"main": "plugin/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"format": "npx @biomejs/biome check --use-editorconfig=true --write plugin/ tests/ bin/ public/",
|
|
8
8
|
"lint": "npx @biomejs/biome check --use-editorconfig=true plugin/ public/",
|
|
9
|
-
"test": "node --test
|
|
9
|
+
"test": "node --test \"tests/*.test.js\""
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
|
-
"node": ">=22.
|
|
44
|
+
"node": ">=22.12.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
+
"@openwaters/almanac": "^0.8.0",
|
|
47
48
|
"@openwaters/maritime-zones": "^0.2.1",
|
|
48
|
-
"astronomy-engine": "^2.1.19",
|
|
49
49
|
"satellite.js": "^7.1.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|