|
Some checks are pending
build-gate / build (push) Waiting to run
Driver: "it would be a big win to not have to have 80mb of images in a public folder and let the posters get generated by the website." Downloading a poster used to end at `poster not found (404)` whenever the pre-rendered .webp was absent. It now falls back to rasterising the poster's own HTML in the browser — fetch posters/<id>.html, inline its stylesheet into the <svg>, draw to a canvas, hand back a blob. Same move the prayer packet already makes: generate on click, ship nothing. This unblocks dropping the 41 MB of committed .webp posters without degrading a working feature, which is the part that had to come first. It also covers the KEY CITY poster wall for free — both walls share this component. ⚠ AN SVG LOADED THROUGH <img> IS AN ISOLATED DOCUMENT: it cannot see the host page's CSS, so every var() falls back to its initial value and `fill`'s initial value is BLACK. The packet shipped exactly that bug once (660 of 661 map elements black, no console error). The stylesheet is therefore inlined INTO the svg, and the result is checked by measuring pixels — a blank render throws rather than handing over a black rectangle. Verified by check:poster-raster: laos rasterises to 3000x4000 with luminance 229 and 54 distinct colours; strip the <style> block and it drops to 13 and 2 colours and the gate fires. WHAT I MEASURED AND REJECTED ALONG THE WAY, so nobody repeats it: shipping the poster HTML *instead of* the webp looked like a clean win on the first sample (laos: 115 KB gzipped vs 213 KB webp) and does NOT generalise — poster HTML scales with geometry complexity while webp is a fixed-resolution raster, so asia-india-rajasthan is 414 KB gzipped vs 239 KB webp. Generalising from one sample is how that idea nearly shipped. Also measured: 351 of the 378 committed posters (35.4 MB) are city-* posters belonging to the Key Cities feature, not to any of the 29 UPG-100 lists. They are a live feature, not dead weight — which is why this lands as a fallback in the shared component rather than a deletion. encodeURIComponent, not btoa, for the data URL: the posters carry non-Latin-1 people-group and place names and btoa throws on those. |
||
|---|---|---|
| .. | ||
| 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.