Files
by-ae-ComfyUI-ByAE-Ideogram…/web/js/ideogram4_shared.js
T
18524ccfa7 fix: report store load failures instead of an empty library
A failed GET /byae/ideogram/stores was caught and replaced with empty
buckets, so Load told the user there were no saved scenes. The request
error now reaches the existing alert, and an empty library is reported
only when the server actually returns one.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: AE <by-ae@users.noreply.github.com>
2026-10-27 21:02:13 +00:00

110 lines
3.4 KiB
JavaScript

/** Shared helpers between the enhanced builder nodes. */
import { nodeClassName } from "./utility.js";
const { app } = window.comfyAPI.app;
export const BUILDER_CLASS = "Ideogram4PromptBuilderKJEnhancedByAE";
export const PREVIEW_UPDATE_CLASS = "Ideogram4PromptBuilderKJPreviewUpdateByAE";
const STORE_API = "/byae/ideogram/stores";
export async function loadStores() {
try {
const resp = await fetch(STORE_API, {
signal: AbortSignal.timeout ? AbortSignal.timeout(5000) : undefined
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
return {
characters: data.characters || {},
objects: data.objects || {},
scenes: data.scenes || {},
};
} catch (e) {
// Callers distinguish a failed request from a library that is actually empty.
console.warn("ByAE Ideogram: failed to load stores", e);
throw e;
}
}
export async function saveStoreEntry(bucket, name, data) {
const resp = await fetch(`${STORE_API}/${bucket}/${encodeURIComponent(name)}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
signal: AbortSignal.timeout ? AbortSignal.timeout(5000) : undefined
});
if (!resp.ok) {
let msg = `HTTP ${resp.status}`;
try {
const err = await resp.json();
if (err?.error) msg = err.error;
} catch (e) { /* ignore */ }
throw new Error(msg);
}
}
export async function deleteStoreEntry(bucket, name) {
const resp = await fetch(`${STORE_API}/${bucket}/${encodeURIComponent(name)}`, {
method: "DELETE",
signal: AbortSignal.timeout ? AbortSignal.timeout(5000) : undefined
});
if (!resp.ok) {
let msg = `HTTP ${resp.status}`;
try {
const err = await resp.json();
if (err?.error) msg = err.error;
} catch (e) { /* ignore */ }
throw new Error(msg);
}
}
export function findBuildersOnGraph(graph) {
if (!graph?._nodes) return [];
return graph._nodes.filter((n) => nodeClassName(n) === BUILDER_CLASS);
}
let _bgPushListenerInstalled = false;
/** Listen for server push when Preview BG Update writes a temp file. */
export function installBgUpdateListener() {
if (_bgPushListenerInstalled) return;
_bgPushListenerInstalled = true;
const { api } = window.comfyAPI.api;
api.addEventListener("byae_ideogram_bg_updated", ({ detail }) => {
if (!detail?.guid) return;
const graph = app.graph;
if (!graph?._nodes) return;
for (const node of findBuildersOnGraph(graph)) {
const guid = node.properties?.byae_bg_guid;
if (guid && guid === detail.guid) {
node.byaeApplyBgUpdate?.(detail);
}
}
});
}
let _queueHooksInstalled = false;
/** Inject internal editor fields into the workflow prompt (no native backing widgets). */
export function installBuilderQueueHooks() {
if (_queueHooksInstalled) return;
_queueHooksInstalled = true;
const orig = app.graphToPrompt?.bind(app);
if (!orig) return;
app.graphToPrompt = async function (...args) {
const builders = findBuildersOnGraph(app.graph);
for (const n of builders) n.byaePersistState?.();
const res = await orig(...args);
if (!res?.output) return res;
for (const n of builders) {
const patch = n.byaeGetPromptInputs?.();
if (!patch) continue;
const key = String(n.id);
if (!res.output[key]) continue;
res.output[key].inputs = { ...(res.output[key].inputs || {}), ...patch };
}
return res;
};
}