Releases: d3mocide/MeshRF
MeshRF v1.16.1 - UI Interaction Patch
Release Date: February 26, 2026
Type: Patch Release (Bug Fixes)
Focus: Resolving UI interaction bugs caused by map event propagation blocking.
🎯 Overview
This patch release fixes a widespread issue where UI panels (Link Analysis, Batch Nodes, Viewshed Control, etc.) became unresponsive or non-resizable due to Leaflet capturing and blocking synthetic React events. By switching to capture-phase event listeners, all panels are fully interactive again.
Full Changelog: CHANGELOG.md
Previous Release: v1.16.0
MeshRF v1.16.0 - Major Refactoring & Modularization
Release Date: February 26, 2026
Type: Minor Release (Architecture Update)
Focus: Codebase restructuring, modularization, and maintainability improvements.
🎯 Overview
This release focuses entirely on structural architecture and technical debt reduction. The codebase has undergone a major refactor to decompose monolithic files, separate concerns, and establish a cleaner foundation for future feature development. All existing functionality has been preserved and verified against automated test suites.
🏗️ Refactoring Highlights
Frontend Architecture
- Component Decomposition: Massive components like
MapContainer.jsxandSidebar.jsxhave been broken down into specialized layers (LinkLayerManager,CoverageLayerManager) and sections (HardwareSection,EnvironmentSection). - State Management: Implemented Facade pattern for React Context (
RFContext.jsxwrapping isolated domains). - RF Math Modularization: Split the monolithic
rfMath.jsinto isolated mathematics modules (fspl.js,bullington.js,earth.js, etc.) located insrc/utils/math/. - Worker & Data Hooks: Standardized Web Worker interactions via
useWorkerState.jsand extracted map tile fetching totileFetcher.js.
Backend API Structure
- API Routing:
server.pyhas been decomposed into dedicated FastAPI routers (routers/analysis.py,routers/elevation.py, etc.). - Tile Manager Extraction: Separated
tile_manager.pylogic intocache_layer.py,elevation_client.py, andgrid_processor.py.
📊 Impact & Stability
- Components Extracted/Created: 25+
- Lines of Code Relocated: ~4,000+
- Test Status: All backend (
pytest) and frontend (vitest) test suites are passing. - Docker Containers: Rebuilt and stable.
Full Changelog: CHANGELOG.md
Previous Release: v1.15.5
Release v1.15.5 - Stability & Reliability Patch
Release Date: February 15, 2026
Type: Patch Release
Focus: Critical bugfixes, memory leak prevention, and WASM binding corrections
🎯 Overview
This patch addresses 18 critical stability issues discovered through systematic code review, including infinite loops, memory leaks, race conditions, silent failures, and a critical WASM binding bug that prevented the ITM propagation model from functioning correctly.
🐛 Critical Fixes
Backend (Python - 7 fixes)
| Issue | Impact | Fix |
|---|---|---|
| SSE Infinite Loop | Open HTTP connections indefinitely | Added 600-poll max timeout (5 min) |
| Silent Exception Swallowing | Errors hidden, debugging impossible | Structured logging with error summaries |
| False-Positive Perfect Links | Misleading "100% clearance" reports | Evaluation flag prevents 0-point analysis |
| ThreadPoolExecutor Leaks | Thread count grows unbounded | shutdown() + __del__() methods |
| Missing Timeouts | Indefinite blocking on tile fetches | 30s timeout with TimeoutError handling |
| Unbounded tile_locks | Memory exhaustion over time | OrderedDict LRU cache (1000 limit) |
| Wrong HTTP Status Codes | 500 errors for client mistakes | Differentiated 400 vs 500 responses |
Frontend (React/JS - 10 fixes)
| Issue | Impact | Fix |
|---|---|---|
| Stale Message Listeners | Duplicate worker handlers, memory leaks | Moved handler into useEffect |
| Stale Closures | Infinite re-render loops | Restored configRef pattern |
| Document Listener Leaks | Chrome tab memory growth | cleanupRef tracking |
| Missing HTTP Error Checks | Unhandled promise rejections | response.ok validation |
| Silent WASM Failures | Tools silently break | wasmError state + user feedback |
| Scan Double-Submit | Duplicate Celery tasks | isScanning guard |
| Missing Imports | Runtime ReferenceErrors | Added useRef, useEffect |
| Infinite Loop (Post-Fix) | Max update depth exceeded | Removed runAnalysis from deps |
| Model Selection | Changing propagation model doesn't recalculate | Added propagationSettings to deps |
WASM/C++ (1 fix)
| Issue | Impact | Fix |
|---|---|---|
| LinkParameters Constructor | "Module.LinkParameters is not a constructor" | Changed value_object → class_ with .constructor<>() |
📦 Deployment
Updated Files
- Backend:
server.py,rf_physics.py,core/algorithms.py,tile_manager.py - Frontend:
useViewshedTool.js,LinkLayer.jsx,LinkAnalysisPanel.jsx,rfService.js,useRFCoverageTool.js,useSimulationStore.js - WASM:
libmeshrf/src/bindings.cpp,meshrf.wasm(109KB),meshrf.js(48KB)
Verification
- ✅ Frontend build successful
- ✅ Python syntax validated
- ✅ WASM module compiled (100%)
- ✅ Runtime errors resolved
🚀 Upgrade Instructions
Development
# Frontend (uses Vite HMR - no restart needed)
# Code changes already live via volume mount
# Backend - restart to reload Python modules
docker restart rf_engine_dev
# Hard refresh browser to load new WASM
Ctrl + Shift + R (Windows/Linux)
Cmd + Shift + R (Mac)Production
# Pull latest code
git pull origin main
# Rebuild containers
docker-compose build
# Restart stack
docker-compose up -d🔍 Testing Recommendations
- Link Analysis: Test ITM (Longley-Rice) propagation model - should no longer throw constructor errors
- Long-Running Scans: Verify SSE endpoints timeout gracefully after 5 minutes
- Memory Monitoring: Check thread count and Redis tile cache remain bounded
- Error Visibility: Confirm viewshed errors appear in logs instead of being silently swallowed
- Multi-Click Protection: Spam-click "Start Scan" button - should only run once
📊 Impact Summary
| Category | Fixes | Severity |
|---|---|---|
| Infinite Loops | 1 | 🔴 Critical |
| Memory Leaks | 3 | 🔴 Critical |
| Silent Failures | 4 | 🟠 High |
| Race Conditions | 2 | 🟠 High |
| Error Handling | 4 | 🟡 Medium |
| Import Errors | 3 | 🟡 Medium |
Total: 18 issues resolved
🙏 Acknowledgments
All issues identified through systematic code review and production debugging. Special attention given to resource management (threads, listeners, locks) and React hook dependency management.
Full Changelog: CHANGELOG.md
Previous Release: v1.15.4
Release v1.15.4: Production Hotfix
This hotfix resolves critical issues preventing the production Docker build from running correctly.
🐛 Bug Fixes
Infrastructure
- Frontend Startup Crash: Fixed a line-ending issue (CRLF) in
docker-entrypoint.shthat prevented the Nginx container from starting. Added.gitattributesto prevent recurrence. - API Connectivity (502): Fixed a port mismatch in
docker-compose.yml. Therf-engineservice now correctly listens on port5001(was80), aligning with the Nginx proxy configuration.
Upgrade Instructions
Rebuild containers to apply the entrypoint fix:
docker-compose down
docker-compose up -d --buildRelease v1.15.3: Security Hardening & Stability
This patch release focuses on critical security remediations and backend stability improvements.
🔒 Security Hardening
Infrastructure & Config
- Redis Authentication: Enabled password protection for the Redis database service, ensuring the data layer is secure.
- Environment Safety: Removed
process.envusage from the frontend build process to prevent potential leakage of secrets. - CORS Restriction: Tightened API access control to allow requests only from localhost origins.
Input & Output Validation
- Coordinate Validation: Added strict validation for latitude/longitude bounds to reject invalid geographic data early.
- Rate Limiting: Introduced rate limits on expensive simulation endpoints to prevent abuse and denial-of-service scenarios.
- KML Sanitization: Implemented XML escaping for KML exports to neutralize potential injection vectors.
🐛 Bug Fixes
Worker Stability
- Connection Pooling: Fixed a critical issue where the background worker would exhaust system sockets (
Error 99) during heavy multi-site scans. Implemented proper Redis connection pooling to reuse connections efficiently.
Upgrade Instructions
Requires a restart of the backend services to apply new Redis password configurations:
Update your docker-compose.yml file, use the included docker file as an example
docker-compose down
docker-compose up -d --buildRelease v1.15.2: Mobile Polish & UI Refinements
This patch release focuses on optimizing the mobile experience and refining the user interface to maximize screen real estate and usability.
📱 Mobile Experience
Layout Optimizations
- Viewshed Control Panel: Now correctly anchored to the bottom of the screen on mobile devices, ensuring easy access without blocking the map view.
- Guidance Overlays: Repositioned to the top of the screen on mobile to avoid overlapping with bottom controls, with adjusted spacing to clear the top toolbar.
- Advanced RF Settings: The floating settings box has been moved (offset
190pxfrom bottom) to sit perfectly above the main control panel.
🎨 UI Refinements
Compact Controls
- Greedy Optimization: The "Greedy Optimization" toggle in the Multi-Site Manager has been redesigned into a compact, single-line control. This reduces visual clutter and provides more room for the node list.
Documentation
- Accuracy: Fixed a typo in the Viewshed guidance text to correctly refer to the visible area as "Purple" instead of "Green".
Upgrade Instructions
No special actions required. This is a frontend-only update.
Release v1.15.1: Viewshed Stability & Dynamic Grid
This patch release addresses critical rendering bugs in the Viewshed tool and implements a new Dynamic Grid Stitching engine to support long-range analysis without clipping.
🚀 Key Improvements
Dynamic Grid Sizing (No More Clipping)
Previously, the viewshed tool was limited to a fixed 3x3 tile grid (approx. 30km radius), causing the analysis to be "cut off" at the edges for long-distance calculations.
- New Logic: The engine now acts intelligently, calculating exactly how many elevation tiles are needed to cover your requested radius.
- Result: Whether you scan 10km or 100km, the system automatically fetches and stitches a 5x5, 7x7, or larger grid to ensure zero clipping.
Visual Clarity
- Shadows Removed: We found that rendering obstructed areas as "faint purple" was confusing. We have disabled shadow rendering, so obstructed areas are now fully transparent. This makes the "True Coverage" stand out clearly against the dark map.
- Radius Adjustment: Default Multi-Site scan radius set to 7.5 km, offering 50% more range than before while maintaining fast scan times.
- Radius Boundary: A Cyan Dashed Circle now appears around the observer, showing you exactly where the calculation limit is.
Stability Fixes
- Crash Fix: Resolved a generic "React Error" that would occur when placing the Viewshed marker rapidly.
- Height Persistence: Fixed a bug where moving the marker would reset your custom Antenna Height to the default 2m.
- Slider Fix: The "Recalculate" button now reliably respects the Distance Slider value instead of reverting to defaults.
🛠️ UI Polish
- Progress Bar: The progress bar now turns Neon Green and fills to 100% when the calculation finishes, giving better feedback.
Upgrade Instructions
No special actions required. This is a frontend-only update.
Release v1.15.0: Viewshed Tool UX Overhaul
This release delivers a comprehensive UX refresh for the Viewshed Analysis tool, including visual theming, performance improvements, and critical bug fixes.
✨ Visual Enhancements
Purple Theming
The Viewshed tool now features consistent purple branding (#a855f7) throughout:
- Purple viewshed overlay with transparency for better map readability
- Purple distance slider with dynamic progress fill showing the selected range
- Purple "Recalculate Viewshed" button with smooth hover effects
Custom SVG Markers
- Replaced PNG marker icons with inline SVG for instant rendering (zero loading delay)
- Markers feature branded cyan color (
#00f2ff) with drop shadows for visual depth - No more waiting for marker assets to load when placing points
Dark Glassmorphism Theme
All Leaflet UI elements now use custom dark glassmorphism styling:
- Popups and tooltips with dark background (
rgba(10, 10, 18, 0.95)) - Neon cyan borders and subtle glow effects
- Backdrop blur for a modern, professional aesthetic
- Fully integrated with the application's cyberpunk design language
Improved Animations
- Guidance overlays now use
slideUpanimation (0.3s ease-out) instead offadeIn - More contextually appropriate for bottom-anchored floating panels
- Smoother, more polished user experience
🐛 Critical Bug Fixes
Recalculate Button
Fixed a critical bug where the "Recalculate Viewshed" button was completely non-functional:
- Root cause: Function signature mismatch in
runViewshedAnalysis - Solution: Updated function to accept both object pattern
({lat, lng}, maxDist)and individual pattern(lat, lng, height, maxDist) - Users can now adjust the distance slider and click "Recalculate" to update the viewshed overlay
Marker Drag Behavior
- Corrected the viewshed marker's
dragendevent handler - Now properly triggers new analysis when markers are moved
- Parameters are passed correctly to the analysis engine
Click-Through Issue
- Fixed pointer-events on the ViewshedControl floating panel
- Map interactions (pan, zoom, click) now work properly even when the panel is visible
Module Import Warning
- Resolved ES6 module import order warning in
useViewshedTool.js - All imports are now at the top of the file per JavaScript module standards
⚙️ Configuration Updates
- Default Antenna Height: Increased from 5 meters to 9.144 meters (30 feet) for more realistic baseline scenarios
🧹 Code Cleanup
- Removed redundant "Viewshed Observer" tooltip (was redundant with popup)
- Cleaned up all debug console logs added during troubleshooting
- Improved code organization and readability
Developer Notes
This release focused on polish and bug fixes for the Viewshed tool. The custom SVG markers and dark theme styling apply globally to all map markers and Leaflet UI components, improving consistency across the entire application.
The function signature fix for runViewshedAnalysis ensures compatibility with multiple calling patterns, making the API more flexible for future enhancements.
Release v1.14.3: Neon Aesthetics & Backend Regression Fixes
This release focuses on verifying the stability of the Multi-Site Analysis tool and aligning its visual output with the application's "Classic Cyberpunk" aesthetic.
🎨 Aesthetics & Branding
- Neon Cyan Coverage: The Multi-Site coverage overlay now renders in glowing Neon Cyan (
#00f2ff) with transparency, replacing the previous monotone texturing. This ensures the coverage map feels like an integrated part of the UI rather than a separate layer.
🐛 Bug Fixes
- Multi-Site Zero Coverage: Fixed a critical backend regression where type mismatches (strings vs floats) caused the viewshed engine to return empty results for all sites.
- Frontend Crash: Resolved an
Invalid LatLngexception by ensuring the Python backend returns bounding boxes in the format expected by the React frontend ({north, south, east, west}). - Invisible Overlay: Fixed a rendering issue where the composite coverage map was calculated but never displayed on the canvas.
For the major mesh planning features introduced in v1.14.0, please refer to the corresponding release notes.
v1.14.0: Mesh Link Intelligence
This release transforms the Multi-Site Analysis tool from a simple coverage area reporter into a full mesh network planning suite. After running a scan you can now immediately answer the questions that matter most: which sites can talk to each other, how much does each site uniquely contribute, and is the proposed network actually a connected mesh?
What's New
1. Inter-Node Link Quality Matrix
Every site pair in your scan is now automatically analysed for RF link viability using the same Bullington terrain-diffraction model used elsewhere in the tool. The new Links tab shows:
| Field | What it tells you |
|---|---|
| Status | Viable / Degraded / Blocked based on Fresnel zone clearance |
| Path Loss | End-to-end path loss in dB — compare against your link budget |
| Fresnel Clearance | % of first Fresnel zone clear at the worst obstruction point |
| Distance | Haversine distance between the two sites |
Links are sorted viable-first so the best candidates are always at the top.
2. Marginal Coverage per Site
The Sites tab now shows how much unique area each node contributes — area that no other selected site covers. This catches redundant placements before you deploy:
- High unique % (cyan) → critical site, removing it creates a coverage gap.
- Low unique % (red) → redundant placement, consider relocating.
3. Mesh Connectivity Score & Topology Tab
The new Topology tab gives a network-level health summary:
- Mesh Connectivity Score — percentage of all node pairs that can communicate, either directly or via relay. A fully connected mesh scores 100%.
- Multi-hop relay detection — BFS pathfinding finds pairs that are blocked on a direct link but reachable through intermediate nodes, with the hop count shown.
- All-pairs path table — every combination of sites with its shortest viable path and status.
4. Link Lines on the Map
Coloured polylines are drawn between every site pair when results are shown, so the topology is visible directly on the terrain:
- Solid cyan — viable direct link
- Dashed gold — degraded link (partial terrain obstruction)
- Dashed red — blocked (no direct LOS path)
5. Combined Coverage Total
The results panel header now shows the total union coverage area of all selected sites — the actual unique terrain covered by the entire proposed network, not the sum of individual footprints.
Improvements
- Site names from CSV imports are now preserved through the scan and appear in all three tabs and on the map polyline tooltips.
- The Help button is now context-aware — it explains the fields for whichever tab you have open.
- The
/scan/startAPI endpoint now forwards RF parameters (frequency, K-factor, clutter height) into the Celery task so link analysis uses your configured settings.
How to Upgrade
git pull origin main
docker compose -f docker-compose.dev.yml up -d --buildPlan smarter. Know your mesh before you deploy.