C4, first wave. Twenty places each stored the same fact — how to translate when the host never installed vue-i18n — and two of them, usePplrT.js and useNeighborT.js, were whole-file near-duplicates at Jaccard 0.82. That pair was the curation audit's evidence that the guard was being COPIED rather than shared. Both now call library/composables/useOptionalT.js and keep their public names, so no call site changes. ★ THE SPEC ASKED FOR (namespace, fallbackCatalogue) AND THE CATALOGUE IS UNNECESSARY. Every copy imported its own English JSON and hand-walked it after stripping the namespace prefix. But library/i18n builds `messages[locale][area]` keyed by the JSON's own filename, and tStatic() already walks that tree and already falls back to English. So `import enPplr from '.../en/pplr.json'` was a second copy of bytes the bundle already had, and the helper takes one argument. ★ AND IT IS NOT A SIZE REGRESSION, which was the one good reason the narrow import might have existed. The build NARROWS library/i18n's catalogue glob per bundle to the areas internal/i18n-areas.mjs finds in that bundle's source graph (check:i18n-treeshake). A bundle that says 'pplr.' gets the pplr area, not the other thirty. Verified before writing the helper, because "the obvious dedup makes every bundle carry every locale" would have killed it. Resolution order, each step earning its place: the host's own vue-i18n when it installed one, so a host managing locale keeps control; then tStatic, which honours the runtime locale and falls back to English; then the key itself, so a missing string is visible rather than blank. The middle step also covers i18n being present but empty — i18n.t() returns the key unchanged, which every copy of this pattern already treated as "not found". Verified by _qa-cycle/02-builder-cycle/_chk-c4-optional-t-equivalence.mjs: 18 assertions across all three host states, with a branch-for-branch equivalence check against the old hand-written implementation and two negative controls. It extracts and executes the module source, because useOptionalT imports vue-i18n and an i18n index that calls import.meta.glob, which plain Node cannot run. |
||
|---|---|---|
| .. | ||
| architecture | ||
| assets | ||
| contributing | ||
| needs-eyes | ||
| readme-images | ||
| screenshots | ||
| CONTRIBUTING.md | ||
| develop-a-plugin-and-see-it-live.md | ||
| explanation.md | ||
| how-to.md | ||
| README-embed-example.md | ||
| README-embed-gospel-resources.md | ||
| README-SECTION-3-cli-commands.md | ||
| README.md | ||
| reference-capability-exemplars.md | ||
| reference-library-index.md | ||
| reference-universal-props.md | ||
| reference.md | ||
| tutorial.md | ||
| vendored-font-noto-serif-devanagari.md | ||
| why.md | ||
documentation/ — pick your path
"what is this?" "teach me" "how do I …?" "look it up" "all the detail"
│ │ │ │ │
why.md ──────────► tutorial.md ────► how-to.md ────► reference.md ───► architecture/
(2 min, 1 diagram) (first map) (task recipes) (tables) (contracts)
- why.md — the problem and the "map islands" idea. Start here.
- tutorial.md — build your first map, no jargon.
- how-to.md — recipes: embed, iframe, SPA, colors, CDN, mobile, tokens.
- reference.md — config fields, build scripts, the
profile-configcontract. - explanation.md — the model in 15 lines.
- architecture/ — the deep end: full contracts, the per-file catalog.
- README-embed-example.md — the drop-in README used when this bundler is embedded inside a host repo.
- README-embed-gospel-resources.md — the gospel map's URL contract for partner embeds: bring your own ISO 639-3 list, one country, one group, or the zero-access view.
Working on the repo:
- develop-a-plugin-and-see-it-live.md — ★ the golden path: zero to a plugin live, in 6 steps.
- README-SECTION-3-cli-commands.md — every command, per deployment method, with prerequisites.
- reference-capability-exemplars.md — which bundle is at which capability tier (generated).
- reference-library-index.md — the reusable
library/pieces you can import (generated). - CONTRIBUTING.md and contributing/ — how to contribute, and the bar for
library/.
Nothing on the simple path is longer than a few minutes; everything complex lives in
architecture/, linked from where you'd need it.