docs(cyclones): tighten shared-context comments, changelog and notes

This commit is contained in:
German Khokhlov committed 2026-11-06 20:07:56 +04:00
1 parent ea22d16c1a
commit 5e64e599e1
5 files changed
+13 -19

No files matched your search

+3 -4
View File
@@ -1,4 +1,3 @@
- Explicit cyclone selections publish only the currently selected NHC/CPHC
storm into shared context. Switching storms removes the previous identity
without a false eviction event. Deliberate clears remain distinct from feed
disappearance (kvnloo, #847; reviewed by quanticsoul4772).
- Let the voice assistant read the storm you select in Cyclone advisories:
its official advisory, position, intensity and movement. Clearing the
selection and the storm leaving the feed are reported apart (kvnloo, #847).
+6 -7
View File
@@ -742,13 +742,12 @@ geographic seams and releases on disable; forecast animation is not implied.
NHC movement speed is converted from miles per hour to rounded knots by the
proxy; advisory wind intensity is already in knots and is passed through.
Cyclone markers, labels, tracks and cones are hidden beyond the horizon on every map source.
Explicit cyclone selections publish one shared `weather-cyclones` record
with official advisory provenance, source position, the English classification
name and, while the proxy serves its cache, the cache fetch time. Switching
storms selects the replacement before pruning the old record; automatic row
selection never claims global context, and refreshes do not re-announce
selection. Deliberate clear/disable reports `deliberate`; losing the selected
storm from the feed reports `evicted` and assigns no fallback.
Explicitly selecting a storm publishes one shared `weather-cyclones` record:
advisory provenance, source position, the English classification name and,
while the proxy serves its cache, the cache fetch time. The automatic row
selection does not claim shared context; refreshes do not re-announce it.
Clear or disable reports `deliberate`; a storm leaving the feed reports
`evicted`, with no fallback.
Consult the linked official advisory for safety decisions.
Voice and HUD snapshots reuse the existing feedState classifier. Analyst follow-ups retain their original data provenance; current-view results append provenance without replacing legacy fields. HUD context and deterministic telemetry include non-nominal feed state.
+1 -1
View File
@@ -1,7 +1,7 @@
import { createCyclonesLayer } from '../../layers/cyclones/index.js';
import * as context from '../../data/contextStore.js';
/** Wire cyclone selection into the application shared-context owner. */
/** Wire cyclone selection to the application shared context. */
export function createApplicationCyclones(options) {
const browserContext = typeof window !== 'undefined' ? { context } : {};
return createCyclonesLayer({
+1 -3
View File
@@ -116,14 +116,12 @@ export function createCyclonesLayer({
layerId: 'weather-cyclones',
layerName: 'Cyclone advisories',
source: 'NOAA NHC / CPHC',
// Keep official storm names verbatim; layerName identifies the layer.
label: storm.name,
latitude: storm.position.latitude,
longitude: storm.position.longitude,
// At most 12 properties reach the voice summary; keep the list short.
properties: {
classification: storm.classification,
// English source meaning; unknown codes stay unexpanded.
classificationName: Object.hasOwn(
CLASSIFICATION_NAMES,
storm.classification,
@@ -140,7 +138,7 @@ export function createCyclonesLayer({
movementDirectionDegrees: storm.movement?.directionDegrees,
movementSpeedKt: storm.movement?.speedKt,
advisoryUrl: storm.advisoryUrl,
// Present only while the server serves its cache with NHC unreachable.
// Only while the proxy serves its cache because NHC is unreachable.
staleCacheFetchedAt:
snapshot.stale && Number.isFinite(snapshot.fetchedAt)
? new Date(snapshot.fetchedAt).toISOString()
+2 -4
View File
@@ -405,8 +405,7 @@ function harness(
},
};
}
// Runs a test body against the real shared-context store on a stand-in window,
// with the voice runner reading the same store.
// Real shared-context store on a stand-in window; the voice runner reads it.
async function withSharedContext(t, body) {
const previousWindow = Object.getOwnPropertyDescriptor(globalThis, 'window');
const host = new EventTarget();
@@ -657,8 +656,7 @@ test('cyclone clears leave another layer selection and its records alone', async
assert.equal(store.selectedEntityId, 'flight:abc123');
assert.equal(events.length, before);
// A foreign record removed without clearing its selection: a cyclone
// feed failure must not report that selection as evicted by cyclones.
// A cyclone feed failure does not evict a dangling foreign selection.
store.entities.delete('flight:abc123');
let fail = false;
const other = open({