go-int read useCsvExport before importing it and found four things that are only
visible from outside. Every one is a pray-tools assumption this file made
silently, and I could not have told you they were assumptions while there was one
caller. That is what a second consumer is FOR, and it is worth more than the code
it produced.
columns — it exported every key of the row, ordered by EXPORT_FIELDS. go-int's
spec asks for the VISIBLE columns. Their workaround was to project rows before
handing them over, which loses the ordering this file exists to impose. An
explicit `columns` is now taken AS GIVEN, order included, and deliberately NOT
filtered to keys that happen to be present: a column the reader can see must
appear even when every row in this scope has it empty, or the file's shape
would depend on the filter, which is the opposite of what a column picker
promises.
wide — exportCsvAsync always fetched the pray-tools list endpoint. A
static-table dashboard has nothing to widen FROM, so that is a wasted network
call that would also pollute its rows with pray-tools fields. It is skippable,
and it now also short-circuits when there is no source at all, because that
case can be recognised rather than configured.
filename and hookPrefix — 'research-dashboard.csv' and the __rdash* window
hooks were literals. Both are options; both defaults are the existing strings,
and the default matters more than the option here: __rdash* names are read
elsewhere in this tree, so changing it would have broken checks with nothing to
do with this landing.
keyOf — a row identified itself as `slug || id`. go-int's rows carry a slug so
this costs them nothing, but they were right to flag it against
config.data.primaryKey: two spellings of one idea that nothing forced to agree.
EVERY DEFAULT IS TODAY'S BEHAVIOUR, so Big Picture's file is unchanged to the
byte. check:csv-shape and its self-test pass, and check:kit-options-reachable
passes across 21 options — which is the gate that exists because I shipped a dead
option in the commit below this one.
Source only, stacked on kit landing 3. No rebuild beyond the one that branch
already needs.
|
||
|---|---|---|
| .. | ||
| api | ||
| colors | ||
| components | ||
| composables | ||
| constants | ||
| data | ||
| i18n | ||
| layouts | ||
| lists | ||
| 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.