Linear: https://linear.app/tinyland/issue/TIN-1726/effect-pm25-field-service-cached-openaq-viewport-sensors-plus-point
Problem
PM2.5 viewport loading, cancellation, station mapping, kernel estimation, and transmission AOD handoff are currently spread across page-local Svelte state and helper functions. That makes lifecycle behavior harder to test and makes provenance harder to reuse in popovers and the transmission sheet.
Scope
- Add a higher-level Effect service around OpenAQ viewport fetches and PM2.5 point sampling.
- Return a canonical field-sample object containing estimate, confidence, contributing stations, effective station count, nearest station, numeric/null counts, bandwidth/radius, computedAt, and source.
- Own abort/generation behavior and normalized viewport cache keys inside the service layer.
- Replace page-local station mapping/sample assembly with the service output.
Acceptance
- A map tap produces one typed PM2.5 field sample consumed by PointReadout and TransmissionSheet.
- Abort/generation behavior remains race-safe on rapid pan/tap/layer toggles.
- Existing null-exclusion and sparse-confidence behavior from pm25-diffusion remains intact.
- Unit tests cover cancellation, cache-key normalization, sparse/no-reading outputs, and happy-path sample creation.
Related: #275, #271, #253.
Linear: https://linear.app/tinyland/issue/TIN-1726/effect-pm25-field-service-cached-openaq-viewport-sensors-plus-point
Problem
PM2.5 viewport loading, cancellation, station mapping, kernel estimation, and transmission AOD handoff are currently spread across page-local Svelte state and helper functions. That makes lifecycle behavior harder to test and makes provenance harder to reuse in popovers and the transmission sheet.
Scope
Acceptance
Related: #275, #271, #253.