doxa-maps/internal/profile-meta.mjs
Doxa Maps 534bbdd5af Rudder stays out of the Research Gallery and makes no network call on a static host
The gallery added every experimental bundle as a tab, so Rudder's engine probes
(/api/rudder/status, /devices, /events) logged three 404s on every embed of the
gallery. The manifest now carries each profile's meta targets, and the gallery
skips a bundle whose profiles are all corner widgets or declare targets without
"web". Rudder itself contacts its engine only where one can exist: the dev
server, the desktop app, or an explicit apiBase.
2026-09-28 03:12:46 +00:00

40 lines
2.2 KiB
JavaScript

/**
* profile-meta.mjs — the per-profile fields a host reads from <profile>.meta.json, in ONE place.
*
* generate-tree (the built manifest.json) and the dev server's /__plugin-gallery/manifest.json both call
* this, so the dev Studio and the built Studio cannot disagree (rega: the corner widget never mounted in
* dev because only the built manifest carried "widget").
* stage "production" | "experimental" default experimental
* heavy true when the element holds live WebGL contexts
* widget { corner } for a corner widget the Plugin Studio mounts once, fixed
*/
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
const CORNERS = ['bottom-right', 'bottom-left', 'top-right', 'top-left']
export function readProfileMeta(dir, profileName) {
try {
const meta = JSON.parse(readFileSync(join(dir, `${profileName}.meta.json`), 'utf8'))
const corner = meta?.widget?.corner
// The plugin's own display name (label, or title / displayName): what the Plugin Studio rail calls it.
const name = [meta?.label, meta?.title, meta?.displayName].find((v) => typeof v === 'string' && v.trim())
return {
stage: meta?.stage === 'production' ? 'production' : 'experimental',
heavy: meta?.heavy === true,
widget: CORNERS.includes(corner) ? { corner } : null,
label: name ? name.trim() : '',
// Where the plugin runs ("web", "desktop"…); absent = web. A desktop-only plugin is never a gallery tab.
targets: Array.isArray(meta?.targets) ? meta.targets.filter((t) => typeof t === 'string') : null,
}
} catch { return { stage: 'experimental', heavy: false, widget: null, label: '', targets: null } }
}
/** The optional manifest keys for one profile (stage always; heavy / widget only when set). */
export function profileMetaFields(dir, profileName) {
const m = readProfileMeta(dir, profileName)
return { stage: m.stage, ...(m.label ? { label: m.label } : {}), ...(m.targets ? { targets: m.targets } : {}), ...(m.heavy ? { heavy: true } : {}), ...(m.widget ? { widget: m.widget } : {}) }
}
/** A bundle is production if ANY of its profiles says so. */
export const bundleStage = (profiles) => (profiles.some((p) => p.stage === 'production') ? 'production' : 'experimental')