doxa-maps/library/utils
Doxa Maps c99fe68c38 A country map you can drop on one page, without the dashboard around it
DX-life's country pages render nothing where a map belongs. The map they need
has been in this repo since the regions clone landed — it was just unreachable
without loading the whole regions dashboard, a bundle that fetches the people
group list, builds four stat cards, a region chooser and a table, none of which
a country page wants. So this is not a new map. It is the same component, given
its own element and its own bundle.

  <doxa-country-map profile-config='{"countryCodes":["TCD"],"colorByPrayer":true}'>

RegionCountryMap and useRegionsI18n move to library/ because they now have a
second consumer, which is the only thing that earns a place there. Six import
sites updated in this commit; nothing else moved.

THE CONTRACT arrives through profile-config, the channel every element here
uses, so a generated page and a hand-written host page are configured the same
way: countryCodes, center, zoom, bounds, colorByPrayer, researchUrl,
prayBaseUrl. Two translations happen at the edge rather than by widening the
component — colorByPrayer is a boolean here and colorMode a string inside, and
countryCodes accepts an array OR "TCD,NER,MLI", because an HTML attribute is a
string and JSON-inside-an-attribute is the shape people get wrong.

THE ELEMENT FETCHES ITS OWN PINS, and that is what makes prayBaseUrl part of the
contract rather than decoration. An element handed a country code, a base URL
and no way to fetch would draw a country outline with nothing inside it — the
blank page it exists to fix, in a new disguise. Same endpoint, same fields, same
mapping as the dashboard; it asks for a country instead of the world.

THE FIELD LIST TRAVELS WITH THE MAPPING, in peopleGroupPoints.js. The obvious
version of this commit asks for PEOPLE_GROUP_LIST_FIELDS — the list the stats
need — and every pin still draws, every popup comes up empty, and nothing logs
anything. The popup half is what makes it a map you can read, so the two are
one export and neither can be requested without the other. The dashboard's own
request is unchanged: the concatenation produces the identical string.

countryUrl is additive, not in the confirmed contract. The component's country
link needs a base and DX-life's country pages live under /regions/; a host that
sets nothing gets that documented default.
2026-09-29 01:38:07 +00:00
..
.gitkeep doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
apiBaseUrl.js doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
ClusterHelpers.js consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00
colocation.js The prayer map's legends see the pins it draws 2026-09-27 02:17:35 +00:00
countries-meta.js Regions: one rollup, ported from theirs, instead of two copies 2026-09-24 04:01:34 +00:00
countryName.js Big Picture speaks Arabic where it was still speaking English: chrome and data labels 2026-09-28 02:01:46 +00:00
DataSourceManager.js Complete app-profiles->plugin-designs sweep across comments/docs; build green; layouts kept at root (load-bearing) 2026-09-17 18:18:19 +00:00
embedBase.js Shipped comments describe the behaviour instead of quoting a person 2026-09-28 17:40:35 +00:00
embedScript.js One page loaded the same bundle twice and nothing said so 2026-09-29 00:06:51 +00:00
formatCount.js One place decides how a count is punctuated, and it still says en-US 2026-09-27 06:04:08 +00:00
geoUtils.js Research tabs read at 15px; the status red is a step brighter 2026-09-17 02:38:38 -05:00
html.js Map popups show data as text: a people-group name or country field can no longer run script 2026-09-26 05:50:24 +00:00
languageLabel.js The packet's generated description, and the language name it prints was index-ordered 2026-09-28 13:56:06 +00:00
loadPinnedUmd.js One pinned-UMD loader for PPLR and the Wall: library/utils/loadPinnedUmd.js 2026-09-26 07:24:25 +00:00
MSTClusteringUtil.js "MST" clustering draws again: a true spanning tree in under a second instead of a 12-second freeze 2026-09-26 04:38:59 +00:00
NetworkClusteringUtil.js doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
peopleGroupPoints.js A country map you can drop on one page, without the dashboard around it 2026-09-29 01:38:07 +00:00
README.md Host-agnostic share links, token-endpoint chain, dev playground as reusable modules, share/asset gates, validated profile-type vocabulary 2026-09-16 12:10:38 -05:00
viewportScrim.js Land the prayer facet and the scrim helper 2026-09-22 21:50:32 +00:00

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 no import mapboxgl in 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/.