Rename the output folder to dx-maps
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions

Driver decision: no embeddable URL carries "doxa" in its folder. The tree's name is one line in
vite.doxa-maps-build-config.json ("name": "dx-maps"); everything else follows it.

- __DOXA_TREE_NAME__ (the vite define rega landed, from MFE_NAME = internal/_tree-name.mjs) bakes the name into the
  bundles for the runtime code that must recognise the tree in a URL. StackLayout.vue's
  resolveBundleSrc anchored on a literal /doxa-maps/ and would have broken every composite's nested
  bundles on a renamed tree; it now anchors on the define. The Research Gallery's dev fallback uses
  it (one reader: rega's define, not a second one).
- The native shells follow via internal/sync-app-shells.mjs: capacitor webDir public/dx-maps, Tauri
  frontendDist ../../public/dx-maps (its window url is tree-relative since the one-folder landing).
- The WordPress contract test reads the name from config instead of carrying three literals.
- check:locale-reachable extracted detectLocale alone and died with "localeFromUrl is not defined"
  after 09d03c60 factored a helper out; it now follows the calls it makes (already red on main).
- generate-tree removes its temp asset pool even when it crashes (a failed build leaked ~50 MB into
  /tmp each time; measured on a full disk).
- Capability exemplars regenerated for the new paths.

Proof: rm -rf public && bun run build -> public/ = README.md + dx-maps/; the 25 built bundles carry
zero 'doxa-maps/' paths (scanned); check:sri, check:drop, check:parse, check:public-hygiene PASS.
Tag names (doxa-* -> dx-*) are the next, separate landing.
This commit is contained in:
doxa-maps-88655c70 2026-09-25 19:26:12 +00:00
parent cc5252b563
commit 09014f8a03
546 changed files with 178 additions and 154 deletions

View file

@ -15,7 +15,7 @@
"\u26a0\ufe0f SOFT FAILURE: a wrong webDir yields an EMPTY assets/public and a BLANK WHITE SCREEN at launch, not an", "\u26a0\ufe0f SOFT FAILURE: a wrong webDir yields an EMPTY assets/public and a BLANK WHITE SCREEN at launch, not an",
"error. After every sync, verify deployment/capacitor/android/app/src/main/assets/public/index.html exists (`bun run cap:verify`)." "error. After every sync, verify deployment/capacitor/android/app/src/main/assets/public/index.html exists (`bun run cap:verify`)."
], ],
"webDir": "public/doxa-maps", "webDir": "public/dx-maps",
"server": { "server": {
"//": [ "//": [
"Capacitor defaults are deliberately kept: iosScheme 'capacitor', androidScheme 'https', hostname", "Capacitor defaults are deliberately kept: iosScheme 'capacitor', androidScheme 'https', hostname",

View file

@ -4,7 +4,7 @@
"version": "0.1.0", "version": "0.1.0",
"identifier": "life.doxa.maps", "identifier": "life.doxa.maps",
"build": { "build": {
"frontendDist": "../../public/doxa-maps", "frontendDist": "../../public/dx-maps",
"beforeBuildCommand": "" "beforeBuildCommand": ""
}, },
"app": { "app": {

View file

@ -52,7 +52,7 @@ $out = do_shortcode_call('doxa_map', [
'bundle' => $target['bundle'], 'bundle' => $target['bundle'],
'element' => $prof['element'], 'element' => $prof['element'],
'profile' => $prof['id'] ?? $prof['name'] ?? $target['bundle'], 'profile' => $prof['id'] ?? $prof['name'] ?? $target['bundle'],
'base' => 'https://nuxtbase.app/plugin-assets/doxa-maps', 'base' => 'https://nuxtbase.app/plugin-assets/'.$tree,
'integrity' => $integrity, 'integrity' => $integrity,
]); ]);
global $SCRIPTS, $INLINE; global $SCRIPTS, $INLINE;
@ -76,7 +76,7 @@ $cfg = json_decode($json, true);
$assert('profile-config is valid JSON', is_array($cfg), $json ? substr($json,0,60) : 'no match'); $assert('profile-config is valid JSON', is_array($cfg), $json ? substr($json,0,60) : 'no match');
// 3. the script src equals the manifest's catalog path for this bundle // 3. the script src equals the manifest's catalog path for this bundle
$src = reset($SCRIPTS)['src'] ?? ''; $src = reset($SCRIPTS)['src'] ?? '';
$want = "https://nuxtbase.app/plugin-assets/doxa-maps/{$target['bundle']}/{$target['bundle']}.js"; $want = "https://nuxtbase.app/plugin-assets/{$tree}/{$target['bundle']}/{$target['bundle']}.js";
$assert('script src matches catalog path', $src === $want, $src); $assert('script src matches catalog path', $src === $want, $src);
// 4. SRI: the filter must add integrity to the emitted <script> tag // 4. SRI: the filter must add integrity to the emitted <script> tag
$handle = array_key_first($SCRIPTS); $handle = array_key_first($SCRIPTS);
@ -86,7 +86,7 @@ $assert('crossorigin anonymous present', str_contains($tag, 'crossorigin="anonym
// 5. a BAD integrity must be REJECTED (negative test — the format regex must actually fire) // 5. a BAD integrity must be REJECTED (negative test — the format regex must actually fire)
$SCRIPTS = []; $SCRIPTS = [];
$out2 = do_shortcode_call('doxa_map', ['bundle'=>$target['bundle'],'element'=>$prof['element'], $out2 = do_shortcode_call('doxa_map', ['bundle'=>$target['bundle'],'element'=>$prof['element'],
'profile'=>$prof['id']??$target['bundle'],'base'=>'https://nuxtbase.app/plugin-assets/doxa-maps', 'profile'=>$prof['id']??$target['bundle'],'base'=>'https://nuxtbase.app/plugin-assets/'.$tree,
'integrity'=>'not-a-valid-hash!!']); 'integrity'=>'not-a-valid-hash!!']);
$h2 = array_key_first($SCRIPTS); $h2 = array_key_first($SCRIPTS);
$tag2 = apply_filters('script_loader_tag', "<script src='x' id='$h2-js'></script>", $h2, 'x'); $tag2 = apply_filters('script_loader_tag', "<script src='x' id='$h2-js'></script>", $h2, 'x');

View file

@ -4,7 +4,7 @@
> check:capability-exemplars` fails if this file falls behind the manifest. > check:capability-exemplars` fails if this file falls behind the manifest.
> >
> This answers one question authoritatively: **which bundles are the capability-N > This answers one question authoritatively: **which bundles are the capability-N
> examples right now?** It is derived from `public/doxa-maps/manifest.json`, which is what > examples right now?** It is derived from `public/dx-maps/manifest.json`, which is what
> the build computed from each folder's real shape — so it cannot drift from what ships. > the build computed from each folder's real shape — so it cannot drift from what ships.
> >
> **Cite this file rather than remembering.** The same citation has been wrong in three > **Cite this file rather than remembering.** The same citation has been wrong in three

View file

@ -64,8 +64,24 @@ if (!body) {
console.error(' stopped testing anything.') console.error(' stopped testing anything.')
process.exit(1) process.exit(1)
} }
// …and every top-level helper of the same file that detectLocale CALLS, transitively. 09d03c60 moved
// the URL half into localeFromUrl(), and a gate that extracted detectLocale alone died with
// "localeFromUrl is not defined" on every case — reporting a working feature as broken. Following the
// calls keeps the gate on the shipped code whatever it is factored into.
const helpers = []
const seen = new Set(['detectLocale'])
const queue = [body]
while (queue.length) {
const code = queue.shift()
for (const [, name] of code.matchAll(/\b([A-Za-z_$][\w$]*)\s*\(/g)) {
if (seen.has(name)) continue
seen.add(name)
const fn = extractFunction(src, name)
if (fn) { const clean = fn.replace(/\bexport\s+/g, ''); helpers.push(clean); queue.push(clean) }
}
}
const make = new Function('SUPPORTED_LOCALES', 'window', 'document', const make = new Function('SUPPORTED_LOCALES', 'window', 'document',
`${body}\n; return detectLocale;`) `${helpers.join('\n')}\n${body}\n; return detectLocale;`)
const detect = (search, htmlLang) => const detect = (search, htmlLang) =>
make(SUPPORTED, { location: { search } }, { documentElement: { lang: htmlLang } })() make(SUPPORTED, { location: { search } }, { documentElement: { lang: htmlLang } })()

View file

@ -1451,6 +1451,10 @@ function main() {
// sibling it used to be was also a trap: it made a sibling-relative asset path resolve locally // sibling it used to be was also a trap: it made a sibling-relative asset path resolve locally
// while it 404'd live (library/utils/embedBase.js records that incident). // while it 404'd live (library/utils/embedBase.js records that incident).
const pubAssets = mkdtempSync(join(tmpdir(), `${TREE_NAME}-assets-`)) const pubAssets = mkdtempSync(join(tmpdir(), `${TREE_NAME}-assets-`))
// …and removed even if this script dies part-way: an 'exit' handler runs on a crash too. A pool left
// behind by a failed build is ~50 MB in /tmp, and on a full disk (2026-09-25) that is what fails the NEXT build.
const dropPool = () => { try { rmSync(pubAssets, { recursive: true, force: true }) } catch { /* already gone */ } }
process.once('exit', dropPool)
// EVERY profile's previews, not just the 100-list's. This was hardcoded to // EVERY profile's previews, not just the 100-list's. This was hardcoded to
// my-upg-100-list, so country-posters shipped with zero thumbnails and its // my-upg-100-list, so country-posters shipped with zero thumbnails and its
// whole wall fell back to "poster not generated yet" placeholders even though // whole wall fell back to "poster not generated yet" placeholders even though

View file

@ -101,11 +101,15 @@ const _stlLoaded = {}
// Anything already absolute, protocol-relative or root-relative is passed through untouched; if no // Anything already absolute, protocol-relative or root-relative is passed through untouched; if no
// /doxa-maps/ segment is found (a foreign mount) the original string is returned, so this can only // /doxa-maps/ segment is found (a foreign mount) the original string is returned, so this can only
// ever fix a path, never break one that was already working. // ever fix a path, never break one that was already working.
// eslint-disable-next-line no-undef
const TREE_SEGMENT = (typeof __DOXA_TREE_NAME__ !== 'undefined' ? __DOXA_TREE_NAME__ : 'doxa-maps').replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
function resolveBundleSrc(url) { function resolveBundleSrc(url) {
if (!url || /^(https?:)?\/\//.test(url) || url.startsWith('/')) return url if (!url || /^(https?:)?\/\//.test(url) || url.startsWith('/')) return url
const bare = url.replace(/^(\.\.\/)+/, '').replace(/^\.\//, '') const bare = url.replace(/^(\.\.\/)+/, '').replace(/^\.\//, '')
// (1) The document is somewhere inside the tree — anchor on its own /doxa-maps/ segment. // (1) The document is somewhere inside the tree — anchor on its own /<tree>/ segment. The name is
const m = /^(.*\/doxa-maps\/)/.exec(window.location.pathname) // baked in at build time (vite define __DOXA_TREE_NAME__, from the build config), never a literal:
// a hardcoded '/doxa-maps/' here broke every composite's nested bundles on a renamed tree.
const m = new RegExp('^(.*/' + TREE_SEGMENT + '/)').exec(window.location.pathname)
if (m) return m[1] + bare if (m) return m[1] + bare
// (2) THE DOCUMENT IS NOT INSIDE THE TREE AT ALL, so there is no segment to anchor on. // (2) THE DOCUMENT IS NOT INSIDE THE TREE AT ALL, so there is no segment to anchor on.
// Driver-reported 2026-09-23: <plugin-studio> mounts at the SERVER ROOT (/index.html) in both // Driver-reported 2026-09-23: <plugin-studio> mounts at the SERVER ROOT (/index.html) in both

View file

@ -2,13 +2,13 @@
This folder is GENERATED by `bun run build`; do not edit it by hand. It holds exactly one thing: This folder is GENERATED by `bun run build`; do not edit it by hand. It holds exactly one thing:
- **`doxa-maps/`** — the output folder: 23 plugin bundles and 35 pages, self-contained. - **`dx-maps/`** — the output folder: 23 plugin bundles and 35 pages, self-contained.
Copy this one folder to any web host (or open it from disk) and it works. Copy this one folder to any web host (or open it from disk) and it works.
- `doxa-maps/index.html` — the front page: the Plugin Studio, every plugin in one place. - `dx-maps/index.html` — the front page: the Plugin Studio, every plugin in one place.
- `doxa-maps/<plugin>/<plugin>.js` — a plugin's bundle (a custom element; load it with a `<script>` tag). - `dx-maps/<plugin>/<plugin>.js` — a plugin's bundle (a custom element; load it with a `<script>` tag).
- `doxa-maps/<plugin>/<page>/index.html` — a ready-made page for one plugin view (embed it in an `<iframe>`). - `dx-maps/<plugin>/<page>/index.html` — a ready-made page for one plugin view (embed it in an `<iframe>`).
- `doxa-maps/manifest.json` — every plugin, page and embed snippet, machine-readable. - `dx-maps/manifest.json` — every plugin, page and embed snippet, machine-readable.
- `doxa-maps/assets/` — the data, fonts and images the plugins fetch at runtime. - `dx-maps/assets/` — the data, fonts and images the plugins fetch at runtime.
The folder's name comes from `name` in `vite.doxa-maps-build-config.json`. Sources live in The folder's name comes from `name` in `vite.doxa-maps-build-config.json`. Sources live in
`plugin-designs/`, `library/` and `data/`; `rm -rf public/ && bun run build` recreates all of this. `plugin-designs/`, `library/` and `data/`; `rm -rf public/ && bun run build` recreates all of this.

View file

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 304 KiB

View file

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View file

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View file

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View file

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View file

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View file

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View file

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View file

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View file

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View file

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View file

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View file

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Some files were not shown because too many files have changed in this diff Show more