doxa-maps/plugin-designs/regions-dashboard
Doxa Maps 3c69770422 C2: one library helper for per-engine projection, across 12 call sites in 9 plugins
SPEC-LIBRARY-CURATION.md's first migration, in the order the shepherd approved.
Source only; studio rebuilds (rule 5B — library/ plus eight other owners' plugins).

THE ASYMMETRY, which is why 12 sites each solved it or failed at it separately:
    Mapbox    getProjection() -> { name }               setProjection('mercator')
    MapLibre  getProjection() -> { type } | undefined   setProjection({ type: 'mercator' })
Passing the Mapbox shape to MapLibre THROWS. Measured on regions-dashboard, where
the throw aborted the camera fly so a region dashboard never framed its region.

WHAT THE 12 SITES WERE DOING:
  · NINE passed a bare string, so on MapLibre the projection silently never changed.
    Eight swallowed the throw in a try/catch; doxa-simple-map.vue:1244 did NOT, so
    there it threw uncaught.
  · TWO had solved it independently and differently: pplr-data-maps'
    setProjectionFor() (instance-tested — the correct one, and the shape adopted)
    and regions-dashboard's local pair (config-derived, which is weaker: it trusts
    what the page was configured with rather than what the map IS).
  · ONE probed by exception, trying the object form and falling back on throw.

The helper reads the engine from the INSTANCE, never from config, because a page can
hold a map built by the other engine. Both functions return something observable —
setProjectionOn returns whether it applied, projectionOf returns null rather than
throwing — on upg100-plugin's argument that a precondition which bails without
recording it is indistinguishable from the request never arriving.
pplrData.setProjectionFor stays as a delegating named export so its three views need
no change.

GATE: _chk-c2-projection-helper-equivalence.mjs, 20 assertions. It runs all THREE old
patterns and the helper against the same stub maps and compares outcomes, rather than
testing the helper alone. Controls prove pattern A really does fail on MapLibre and
leave the projection untouched, and that the bare string really throws — so the
"equivalence" claim has something to be equivalent to. A NEG control catches a helper
that reports success it did not achieve.

★ I DESTROYED 984 LINES OF ANOTHER TEAM'S CODE GETTING HERE, and only the build caught
it. My import-inserting script did `s[:at] + IMPORT` and never appended `s[at:]`, so
every file where the import was ADDED rather than extended was truncated at its last
import line: MapCell.vue -458, FlowerClusters.vue -334, lang-cluster.vue -192.
check:no-free-identifiers PASSED on all three, because a truncated script block is
still valid script. Restored from HEAD and redone with an assertion that a migration
must change the line count by exactly +1 and never remove a line — which is the check
that would have caught it in the first second.

Verified after: all 9 affected bundles build, both gates green, and a per-file line
delta on all 13 changed files with the only negative being the 2 lines I deliberately
deleted from RegionCountryMap when its local pair became an import.
2026-09-26 08:39:53 +00:00
..
src C2: one library helper for per-engine projection, across 12 call sites in 9 plugins 2026-09-26 08:39:53 +00:00
dxlife-tokens.js Port their base line-height (1.5); our 1.1 override was compensating for its absence 2026-09-26 05:33:12 +00:00
index.html Regions element gets the Select View tabs, shared with UPG-100 2026-09-23 19:08:00 +00:00
index.js i18n: 408 strings copied from DX-life, 8 locales, RTL, and the data follows too 2026-09-24 03:00:38 +00:00
region-dashboards.meta.json Regions: the selected page is now an exact clone; the chooser is the one addition 2026-09-24 00:59:10 +00:00
region-dashboards.vue Delete the stat-value shrink: its premise went stale when Bebas was vendored 2026-09-26 06:44:30 +00:00
regions-list.meta.json Regions: the selected page is now an exact clone; the chooser is the one addition 2026-09-24 00:59:10 +00:00
regions-list.vue Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-1/work 2026-09-26 05:42:29 +00:00
regions-mfe.meta.json Regions: the selected page is now an exact clone; the chooser is the one addition 2026-09-24 00:59:10 +00:00
regions-mfe.vue The people-group list is a universal prop: the same maps can show any project's list 2026-09-26 05:16:02 +00:00