mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-05-13 16:23:07 +00:00
a97fa52f10
## Summary Implements **M4 (frontend consumers)** from the [resolved-path spec](https://github.com/Kpa-clawbot/CoreScope/blob/resolved-path-spec/docs/specs/resolved-path.md) for #555. The server (PR #556, M1-M3) now returns `resolved_path` on all packet/observation API responses and WebSocket broadcasts. This PR updates all frontend consumers to **prefer `resolved_path`** over client-side HopResolver, with full fallback for old packets. ## What changed ### `hop-resolver.js` - Added `resolveFromServer(hops, resolvedPath)` — takes the short hex prefixes and aligned array of full pubkeys from `resolved_path`, looks up node names from the existing nodesList. Returns the same `{ [hop]: { name, pubkey, ... } }` format as `resolve()`. ### `packet-helpers.js` - Added `getResolvedPath(p)` — cached JSON parser for the new `resolved_path` field (mirrors `getParsedPath`). - Updated `clearParsedCache()` to also clear `_parsedResolvedPath`. ### `packets.js` - **Bulk load** (`loadPackets`): calls `cacheResolvedPaths(packets)` before the existing `resolveHops` fallback. - **WebSocket updates**: pre-populates `hopNameCache` from `resolved_path` on incoming packets before falling back to HopResolver for any remaining unknown hops. - **Group expansion** (`pktToggleGroup`): caches resolved paths from child observations. - **Packet detail** (`selectPacket`): prefers `resolveFromServer` when `resolved_path` is available. - **Show Route button**: uses `resolved_path` pubkeys directly instead of client-side disambiguation. - **Observation spreading**: carries `resolved_path` field when constructing observation packets. ### `live.js` - `resolveHopPositions` accepts optional `resolvedPath` parameter; prefers server-resolved pubkeys, falls back to HopResolver for null entries. - Normalized WS packet objects now carry `resolved_path`. ### Files NOT changed (no resolution changes needed) - **`analytics.js`** — only uses `HopResolver.haversineKm` (a utility function). Topology, subpath, and hop distance data comes pre-resolved from the server API (handled by M2/M3). - **`nodes.js`** — gets pre-resolved path data from `/nodes/:pubkey/paths` API; no client-side hop resolution. - **`map.js`** — `drawPacketRoute` already handles full 64-char pubkeys via exact match. The updated `packets.js` now passes full pubkeys from `resolved_path` to the map. ## Fallback pattern ```javascript // In hop-resolver.js function resolveFromServer(hops, resolvedPath) { // Returns resolved entries for non-null pubkeys // Skips null entries (unresolved) — caller falls back to HopResolver } // In packets.js — bulk load await cacheResolvedPaths(packets); // server-side first await resolveHops([...allHops]); // client-side fallback for remaining ``` Old packets without `resolved_path` continue to work exactly as before via the existing HopResolver. `hop-resolver.js` is NOT removed — it remains the fallback. ## Tests - 10 new tests for `resolveFromServer()` and `getResolvedPath()` - All 445 frontend helper tests pass - All 62 packet filter tests pass - All 29 aging tests pass Closes #555 (M4 milestone) --------- Co-authored-by: you <you@example.com>
62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
/* === CoreScope — packet-helpers.js (shared packet utilities) === */
|
|
'use strict';
|
|
|
|
/**
|
|
* Cached JSON.parse helpers for packet data (issue #387).
|
|
* Avoids repeated parsing of path_json / decoded_json on the same packet object.
|
|
* Results are cached as _parsedPath / _parsedDecoded properties on the packet.
|
|
*
|
|
* Handles pre-parsed objects (non-string values) gracefully — returns them as-is.
|
|
*/
|
|
|
|
window.getParsedPath = function getParsedPath(p) {
|
|
if (p._parsedPath !== undefined) return p._parsedPath || [];
|
|
var raw = p.path_json;
|
|
if (typeof raw !== 'string') {
|
|
p._parsedPath = Array.isArray(raw) ? raw : [];
|
|
return p._parsedPath;
|
|
}
|
|
try { p._parsedPath = JSON.parse(raw) || []; } catch (e) { p._parsedPath = []; }
|
|
return p._parsedPath;
|
|
};
|
|
|
|
/**
|
|
* Clear cached _parsedPath/_parsedDecoded from a packet object.
|
|
* Must be called after spreading a parent packet into an observation/child,
|
|
* otherwise the child inherits stale cached values from the parent (issue #504).
|
|
*/
|
|
window.clearParsedCache = function clearParsedCache(p) {
|
|
delete p._parsedPath;
|
|
delete p._parsedDecoded;
|
|
delete p._parsedResolvedPath;
|
|
return p;
|
|
};
|
|
|
|
/**
|
|
* Parse resolved_path (server-side resolved full pubkeys).
|
|
* Returns array of pubkey strings (or null entries) if present, or null if absent.
|
|
* Cached as _parsedResolvedPath on the packet object.
|
|
*/
|
|
window.getResolvedPath = function getResolvedPath(p) {
|
|
if (p._parsedResolvedPath !== undefined) return p._parsedResolvedPath;
|
|
var raw = p.resolved_path;
|
|
if (!raw) { p._parsedResolvedPath = null; return null; }
|
|
if (typeof raw !== 'string') {
|
|
p._parsedResolvedPath = Array.isArray(raw) ? raw : null;
|
|
return p._parsedResolvedPath;
|
|
}
|
|
try { p._parsedResolvedPath = JSON.parse(raw) || null; } catch (e) { p._parsedResolvedPath = null; }
|
|
return p._parsedResolvedPath;
|
|
};
|
|
|
|
window.getParsedDecoded = function getParsedDecoded(p) {
|
|
if (p._parsedDecoded !== undefined) return p._parsedDecoded || {};
|
|
var raw = p.decoded_json;
|
|
if (typeof raw !== 'string') {
|
|
p._parsedDecoded = (raw && typeof raw === 'object') ? raw : {};
|
|
return p._parsedDecoded;
|
|
}
|
|
try { p._parsedDecoded = JSON.parse(raw) || {}; } catch (e) { p._parsedDecoded = {}; }
|
|
return p._parsedDecoded;
|
|
};
|