doxa-maps/plugin-designs/prayer-walk-planner/index.js
doxa-maps-88655c70 b862c7d61a Export gate reads the tree name from the build config
After the dx-maps rename, its public/doxa-maps literal made it SKIP (exit 2) without measuring.
Validated against its baseline on the renamed tree: 4/4 one-click exports, 1700x2200 PNGs,
0 errors, as before the rename. Also: usage examples and present-tense comments in the
gallery and planner name /dx-maps/ or the configured tree; both bundles rebuild byte-identical.
2026-09-25 21:32:35 +00:00

57 lines
3.2 KiB
JavaScript

/**
* plugin-designs/prayer-walk-planner/index.js
*
* Bundle entry for PRAYER WALK PLANNER — an experimental capability-1 plugin.
*
* Usage from a host page:
* <script src="/dx-maps/prayer-walk-planner/prayer-walk-planner.js"></script>
* <prayer-walk-planner></prayer-walk-planner>
*
* ★ MOUNTS THE ROOT SFC DIRECTLY — no ProfileLoader. Same choice golden-path-check and
* doxa-vision-card make, and for the same reason: this plugin draws its own MapLibre
* instance via @map/composables/useMapInstance.js with provider:'maplibre' — it needs NO
* Mapbox token, NO dataSource/colorSet wiring, and NO multi-profile switching (ProfileLoader
* exists to parse profile-config JSON and route to one of several flat .vue screens — this
* bundle ships exactly one screen and reads nothing from a profile-config attribute).
* Routing it through ProfileLoader would add three Pinia stores and a config parser this
* component never uses — see golden-path-check/index.js's header for the concrete failure
* that mistake causes (a thrown setup() removes the whole shadow-DOM subtree silently).
*
* ★ CLIENT-SIDE API, NOT A BACKEND. The Driver's brief: "Although this is JAMstack, we're
* not building any API into it. The only API we can build has to be CLIENT SIDE." The root
* component defineExpose()s addPolygon/deletePolygon/selectPolygon/print/list methods.
* Because this bundle mounts the SFC AS the defineCustomElement root (not nested under
* ProfileLoader), Vue's custom-element bridge surfaces those exposed methods directly on the
* DOM element instance — `document.querySelector('prayer-walk-planner').addPolygon(...)`
* works with no further wiring. See prayer-walk-planner.vue's header for the full surface.
*/
import { defineCustomElement } from 'vue'
import PrayerWalkPlanner from './prayer-walk-planner.vue'
import { createAppI18n } from '@map/i18n/index.js'
// ★ configureApp WITHOUT changing the mounting shape. This bundle deliberately mounts the
// SFC AS the custom-element root so Vue's bridge surfaces its defineExpose()d client-side
// API on the DOM element (the Driver's "the only API we can build has to be CLIENT SIDE").
// That decision and i18n are ORTHOGONAL — the second argument takes configureApp whichever
// component is the root, so this keeps addPolygon/print/listPolygons on the element.
//
// ⚠ IT IS REQUIRED, not cosmetic. Any shared component that calls useI18n() — ShareButton
// does — THROWS in setup() without it, and this file's own header records what that costs:
// "a thrown setup() removes the whole shadow-DOM subtree silently." Measured 2026-09-24:
// adding <ShareButton> with no i18n installed produced a SyntaxError at runtime, the whole
// toolbar rendered its other five buttons and the share button simply did not exist —
// while check:share-policy, which counts <ShareButton> in SOURCE, stayed green.
const PrayerWalkPlannerElement = defineCustomElement(PrayerWalkPlanner, {
configureApp(app) {
const i18n = createAppI18n()
app.use(i18n)
app.provide('appI18n', i18n)
}
})
if (typeof customElements !== 'undefined' && !customElements.get('prayer-walk-planner')) {
customElements.define('prayer-walk-planner', PrayerWalkPlannerElement)
}
export default PrayerWalkPlannerElement