Files
olivv-cs-ComfyUI-FunPack/app/catalogue/hide.js
T
digital-garbage 835fab7864 core+shell: the bridge, and the first module through it
One declaration does three jobs: renders the panel, carries the defaults, names
the values that come back. A module writes no DOM and reads no DOM.

Validation refuses rather than repairs -- unknown type, a renderer its type does
not have, a label that is not text, a default outside its own bounds, a when
naming a key the module never declared. A module that is wrong does not get a
best-effort panel; it does not load, and says why once.

Ordering is by declared relation and stage, never priority numbers, and a cycle
drops only the modules in it. Compatibility is by trait, never model name.

The shell hands a module { composer, values, on, shell } and nothing else: no
node, no document, no kit internals. It cannot style anything because it is
never given anything that could.

catalogue/hide.html puts one good module and five broken ones through the real
shell and shows the result: one panel, five absent, no placeholders. The lint
fixtures make the scanner prove it catches each rule, so a clean scan means
something.

First slice: modules/system/appearance. Two settings, an optional ui.js, and
clicking Light actually turns the app light.
2026-08-28 19:58:06 +03:00

87 lines
3.1 KiB
JavaScript

// Renders the fixture modules through the real shell.
import { mountAll } from "../shell/panels.js";
import { offer, _reset as resetMounts } from "../shell/mounts.js";
import { _reset as resetValues, all as allValues } from "../shell/values.js";
import { GOOD, BROKEN } from "./fixtures.js";
const el = (tag, cls, text) => {
const n = document.createElement(tag);
if (cls) n.className = cls;
if (text != null) n.textContent = text;
return n;
};
async function render(theme) {
resetMounts();
resetValues();
const page = document.querySelector("#catalogue");
page.textContent = "";
const section = el("section", "cat-section");
section.append(el("h2", null, "What a user sees"));
section.append(el("p", null,
"Six modules go in: one valid, five broken in different ways. Everything below " +
"is the whole of what reaches the screen."));
const pane = el("section", "cat-pane");
pane.setAttribute("data-theme", theme);
pane.append(el("h3", null, theme));
const host = el("div", "cat-mount");
pane.append(host);
section.append(pane);
page.append(section);
offer("demo.panel", host);
// The broken ones are handed to the shell exactly as the good one is. In the
// real app most never get this far -- core refuses them at import or at
// validation -- so this is the worst case: everything reaching the browser.
const manifest = { modules: [GOOD, ...BROKEN.map((b) => b.spec)] };
const { mounted, hidden } = await mountAll(manifest);
if (!host.childElementCount) host.append(el("p", "cat-broke", "nothing mounted at all"));
// Everything from here down is developer commentary, NOT part of what a user
// would see -- the panel above is.
const ledger = el("section", "cat-section");
ledger.append(el("h2", null, "Why each one is absent"));
ledger.append(el("p", null, "This table exists for you, not for the user. None of it appears in the app."));
const table = el("div", "cat-ledger");
for (const { id } of mounted) {
table.append(el("div", "cat-ledger-row cat-ok"), el("code", "cat-name", id));
table.append(el("span", null, "mounted"));
}
for (const { id, why } of hidden) {
const source = BROKEN.find((b) => b.spec.id === id);
table.append(el("code", "cat-name", id));
table.append(el("span", "cat-why", source ? source.why : "—"));
table.append(el("span", "cat-caught", why));
}
ledger.append(table);
page.append(ledger);
const values = el("section", "cat-section");
values.append(el("h2", null, "Values a headless run would get"));
values.append(el("p", null,
"Seeded from the same declaration the panel renders, so a generation with no " +
"browser open starts from the same numbers."));
const pre = el("pre", "cx-code-block");
pre.textContent = JSON.stringify(allValues(), null, 2);
values.append(pre);
page.append(values);
}
let theme = "dark";
for (const btn of document.querySelectorAll("[data-theme-set]")) {
btn.addEventListener("click", () => {
theme = btn.getAttribute("data-theme-set");
window.ComposerTheme.apply(theme === "auto" ? "auto" : theme);
render(theme === "auto" ? window.ComposerTheme.resolved() : theme);
});
}
render(theme);