Choosing MST on the research map built and sorted every pair of pins (~2.2 million edges for the 2,107-pin roster), ~12 s on the main thread, and then did it all again for a log line. The page froze, and check:clustering-modes read the map before any line existed: "MST drew no cluster lines". - MSTClusteringUtil runs Prim over the implicit complete graph: O(n²) time, O(n) memory, no edge list. Starting a new tree when the nearest outside point is beyond maxConnectionDistance gives the same spanning forest as before. - useMapClustering no longer recomputes every tree for its stats log line. - check:mst-clustering (headless, in gates:post): same edge count and total length as a reference all-pairs Kruskal on 2-400 pins, capped and uncapped; 2,107 pins in 872 ms here (budget 3 s). On the previous code it FAILs at 11,206 ms. |
||
|---|---|---|
| .. | ||
| .gitkeep | ||
| apiBaseUrl.js | ||
| ClusterHelpers.js | ||
| countries-meta.js | ||
| DataSourceManager.js | ||
| embedBase.js | ||
| geoUtils.js | ||
| MSTClusteringUtil.js | ||
| NetworkClusteringUtil.js | ||
| README.md | ||
| viewportScrim.js | ||
library/utils/ — pure JS helpers
No Vue, no Pinia, no Mapbox. Anything reactive is a composable; anything stateful is a store.
| File | Purpose |
|---|---|
apiBaseUrl.js |
Resolves the API base URL at runtime (window.MAP_APP_API_URL / VITE_API_BASE_URL) |
embedBase.js |
Share/embed URL ladder — the built bundle derives its tree root from its own script url (profileConfig.shareUrl / embedBaseUrl / window.MAP_EMBED_BASE_URL override) so tree-relative <bundle>/<profile>/index.html links work on any host |
geoUtils.js |
Centroid, bounds, validation, GeoJSON helpers |
ClusterHelpers.js |
Shared helpers for the two clustering utilities below |
MSTClusteringUtil.js |
Minimum-spanning-tree clustering for affinity blocks |
NetworkClusteringUtil.js |
Network-line clustering — connect nearby pins with edges |
- No
import { ref } from 'vue'and noimport mapboxglin this folder — operate on plain[lng, lat]arrays. - Named exports (for tree-shaking), JSDoc on every export.
- Writing reactive logic or needing Mapbox APIs? That's a composable — move it to
../composables/.