library/maps/rtl-text.js installed the RTL text plugin for MAPBOX only (window.mapboxgl, from api.mapbox.com). So every MapLibre map, i.e. every keyless embed, drew RTL place names as disconnected, reversed glyphs. Measured on the Prayer Walk Planner's printed Arabic sheet. Under it was a second gap. Bundle entries call the installer at LOAD time, before useMapInstance has lazily injected a MapLibre engine, so even an engine-aware installer found nothing to install into. - rtl-text.js is engine-aware. Mapbox is unchanged (same URL, same lazy call). MapLibre gets the same plugin package from jsDelivr, keyless and not api.mapbox.com, so keyless pages still make zero Mapbox requests. New ensureRtlTextPlugin(gl) waits until it is LOADED, for callers that capture a single frame (print). - useMapInstance installs it the moment an engine global exists, the one point every map passes through. - The planner drops its private copy for the shared helper. Measured: a print map of downtown Cairo (MapLibre, keyless) shows shaped Arabic street and place names (شارع التحرير, مسجد الطباخ …); plugin status "loaded", fetched from jsDelivr. check:gallery-embed passes js, iframe, neighbour and linked (14 tabs); :maplibre passes; check:prayer-walk-planner passes. The shared change reaches all 11 bundles that compile initializeMap, and all are rebuilt here. check:shared-reached gains an rtl-text-maplibre marker (10/10 consumers carry it; cities-internet, gospel-resources and my-upg-100-list boot maps another way and are not affected). Also: the new Experimental bundle pplr-data-maps loads the Mapbox geocoder under maplibre (pplrData.js:38). It is an owned, printed MAPBOX_KNOWN entry routed to its owner; delete it in their fix commit. |
||
|---|---|---|
| .. | ||
| api | ||
| colors | ||
| components | ||
| composables | ||
| constants | ||
| data | ||
| i18n | ||
| layouts | ||
| maps | ||
| packet | ||
| scripts | ||
| stores | ||
| styles | ||
| utils | ||
| index.js | ||
| ProfileLoader.vue | ||
| README.md | ||
library/ (@map) — the shared map template
The other half of the architecture (see ../plugin-designs/README.md):
every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here.
Fix something here and every map benefits on the next build; break something here and every map
breaks — read components/WARNING.md before touching shared pieces.
| Folder | What lives there |
|---|---|
ProfileLoader.vue |
The root of every bundle: parses profile-config, loads the profile, provides the stores + config |
components/ |
Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README) |
composables/ |
Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming |
stores/ |
Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children |
api/ |
Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring |
colors/ |
Color sets maps opt into via profile-config.colorSet |
i18n/ |
The shared string catalogs (all maps speak the same languages) |
data/ |
Small shared datasets baked at build time (big served data lives in ../data/) |
constants/ |
Shared constants |
scripts/ |
Maintainer pipelines (posters, research) — not part of any bundle |
The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.