prop/assets/js
Graham McIntire a14f14485e
perf(weather): serve /weather from chunked scalar artifacts
Move the /weather render path off raw HRRR profile decoding + per-cell
SoundingParams + WeatherLayers derivation. The dominant cost was
re-deriving the same scalar fields on every viewport pan and timeline
scrub.

Server side:

- New Microwaveprop.Weather.ScalarFile persists pre-derived scalar
  rows on NFS, bucketed into 5°×5° chunk files under
  <base>/weather_scalars/<iso>/<lat_band>_<lon_band>.etf.gz. Viewport
  reads only decode the chunks that overlap the requested bounds;
  point-detail clicks read exactly one chunk.
- weather_grid_at/2 and weather_point_detail/3 prefer ScalarFile;
  ProfilesFile is now the cold-start fallback only.
- warm_grid_cache_and_broadcast/1 and warm_grid_cache_from_latest_profile/0
  also persist the scalar artifact, and the cold-derive path kicks
  off a per-valid_time-locked async materialization so the next
  reader gets the cheap path.
- NotifyListener.handle_propagation_ready/1 fires
  Weather.materialize_scalar_file/1 in a detached Task on the Rust
  pipeline's NOTIFY propagation_ready, so steady-state forecast hours
  arrive with their scalar artifact already on disk.
- available_weather_valid_times/0 unions ScalarFile + ProfilesFile so
  the timeline survives an aggressive retention sweep on either side.

Browser side (finding #8):

- Mount the legend Leaflet control once and patch its inner content
  on layer changes instead of remove + re-add on every renderLayer.
- renderTimeline now keys off the rendered button set: selection-only
  updates take an applyTimelineSelection patch path that restyles
  existing buttons in place. Full innerHTML rebuild only fires when
  timelineData itself changes.

Also fixes a credo nesting-depth flag in tile_renderer.ex by extracting
interpolate_pair/2 from the inner anonymous function.
2026-04-28 17:15:36 -05:00
..
types feat(eme): 3D WebGL Earth-Moon globe with lazy-loaded Three.js 2026-04-23 17:00:53 -05:00
app.ts feat(rover-locations): inline satellite map per location 2026-04-26 13:55:08 -05:00
beacon_map_hook.ts feat(format): miles-primary distance formatting sitewide 2026-04-18 15:53:40 -05:00
beacons_list_map_hook.ts Beacon list map, profile page polish, nav ordering fix 2026-04-12 16:23:09 -05:00
contact_map_hook.ts refactor: normalize pos1/pos2 JSONB key to 'lon' everywhere 2026-04-17 09:10:32 -05:00
contacts_map_hook.ts feat(format): miles-primary distance formatting sitewide 2026-04-18 15:53:40 -05:00
elevation_profile_hook.ts feat(canopy): add tree-canopy height layer for path obstruction analysis 2026-04-26 12:51:48 -05:00
eme_globe_hook.ts feat(eme): 3D WebGL Earth-Moon globe with lazy-loaded Three.js 2026-04-23 17:00:53 -05:00
format.ts feat(format): miles-primary distance formatting sitewide 2026-04-18 15:53:40 -05:00
horizontal_wheel_scroll_hook.ts feat(rover): make candidate strip scroll horizontally + wheel-to-h-scroll 2026-04-26 09:31:10 -05:00
locate_me_hook.ts Convert all JavaScript to TypeScript with type annotations 2026-04-11 16:59:28 -05:00
location_map_hook.ts fix(rover-locations): use circleMarker; default marker icons aren't bundled 2026-04-26 14:03:10 -05:00
maidenhead_grid.ts feat(grid): show full Maidenhead label at subsquare zoom (em13sf, not sf) 2026-04-26 09:54:08 -05:00
path_forecast_hook.ts feat(path): hover-on-dot factor breakdown + tag fallback factors 2026-04-25 15:33:19 -05:00
propagation_map_hook.ts feat(path): hover-on-dot factor breakdown + tag fallback factors 2026-04-25 15:33:19 -05:00
rover_map_hook.ts feat(rover): add ESRI satellite imagery as base-layer option 2026-04-26 11:52:12 -05:00
rover_slider_hook.ts feat(rover): replace max-drive-time slider with max-distance in miles 2026-04-25 17:21:57 -05:00
weather_map_hook.ts perf(weather): serve /weather from chunked scalar artifacts 2026-04-28 17:15:36 -05:00