Fast_deploy / ComfyUI-MiniMaxH3-Context-Loop /web /h3_kj_preview_bridge.js
dzmdd's picture
Upload folder using huggingface_hub (part 3)
8fb6433 verified
Raw History Blame Contribute Delete
2.95 kB
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import {
H3_LOOP_END_TYPE,
KJ_PREVIEW_TYPE,
fallbackDisplayIds,
recursiveRootId,
} from "./h3_kj_preview_bridge_core.mjs?v=0.6.2";
const executionToDisplay = new Map();
// Mirrors ComfyUI's qualified-id lookup for nodes inside subgraphs.
function findNodeByDisplayId(qid) {
if (!app.graph || qid == null) return null;
const parts = String(qid).split(":");
let graph = app.graph;
for (let i = 0; i < parts.length - 1; i++) {
const parentId = Number(parts[i]);
if (!Number.isFinite(parentId)) return null;
const parent = graph?.getNodeById?.(parentId);
if (!parent?.subgraph) return null;
graph = parent.subgraph;
}
const leafId = Number(parts.at(-1));
return Number.isFinite(leafId) ? graph?.getNodeById?.(leafId) ?? null : null;
}
function nodeType(node) {
return node?.comfyClass ?? node?.type ?? null;
}
function belongsToH3Loop(executionId) {
const rootId = recursiveRootId(executionId);
return rootId != null && nodeType(findNodeByDisplayId(rootId)) === H3_LOOP_END_TYPE;
}
function rememberDisplayMapping(data) {
if (data?.node == null || data?.display_node == null) return;
const executionId = String(data.node);
const displayId = String(data.display_node);
if (executionId === displayId || !belongsToH3Loop(executionId)) return;
if (nodeType(findNodeByDisplayId(displayId)) === KJ_PREVIEW_TYPE) {
executionToDisplay.set(executionId, displayId);
}
}
function resolvePreviewNode(executionId) {
if (!belongsToH3Loop(executionId)) return null;
const candidates = [];
const mapped = executionToDisplay.get(executionId);
if (mapped != null) candidates.push(mapped);
candidates.push(...fallbackDisplayIds(executionId));
for (const displayId of candidates) {
const node = findNodeByDisplayId(displayId);
if (nodeType(node) === KJ_PREVIEW_TYPE) return node;
}
return null;
}
app.registerExtension({
name: "minimax_h3_context_loop.kj_preview_loop_bridge",
setup() {
api.addEventListener("execution_start", () => executionToDisplay.clear());
api.addEventListener("executing", (event) => rememberDisplayMapping(event.detail));
api.addEventListener("kj_preview_override", (event) => {
const data = event.detail;
if (data?.node_id == null) return;
const executionId = String(data.node_id);
// KJ handles ordinary canvas ids itself. We intervene only when its
// source is a generated H3 recursion id that has no canvas node.
if (findNodeByDisplayId(executionId)) return;
const node = resolvePreviewNode(executionId);
if (typeof node?._kjPreviewHandler === "function") {
node._kjPreviewHandler(data);
}
});
},
});