Second site of the defect rega found on regions-mfe, and this one is shared by three
plugins — country-posters, doxa-simple-map and doxa-research-map.
The source asymmetry here was already handled carefully: MapLibre gets a geojson
source instead of the mapbox:// tileset, the loader bridges iso3 -> iso_3166_1_alpha_3,
and the layer drops 'source-layer' because MapLibre rejects it on geojson. What was
missed is one field deeper. countryFilter() also ANDs a worldview clause, which exists
because the tileset repeats a country once per worldview and the outline would otherwise
draw two or three times over. world-adm0.geojson has no such duplication and carries no
worldview property, so ['get','worldview'] is null, both sides of the `any` are false on
every feature, and the `all` admits nothing. The outline is absent with no error, which
looks exactly like boundary data that failed to load.
Unlike the ISO field this cannot be bridged in the loader: there is no worldview to
invent. It is a fact about the tileset's shape, so only the Mapbox path asks for it.
The engine sniff already in the file moves UP, above the filter. It sat inside the
try block, below the line that built the filter, so the filter could not have consulted
it; the fast path at the top (setFilter on an existing layer) reuses the same filter and
is now covered by the same branch.
MEASURED, fail-first, against the real 162 features with MapLibre's own style-spec parser:
the worldview clause admits 0 / 162
the MapLibre branch admits 1 / 1 (== one country, this composable's shape)
the Mapbox path still collapses a duplicate worldview copy to 1
The check also REGISTERS both worldview sites in the tree and fails on a new unlisted
one, so the class cannot come back quietly in a component nobody re-shoots.
Not landed here: three consumer bundles compile this, so it needs their rebuild.
(cherry picked from 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.