Spaces:
Running
on
Zero
Running
on
Zero
var IoDirection; | |
(function (IoDirection) { | |
IoDirection[IoDirection["INPUT"] = 0] = "INPUT"; | |
IoDirection[IoDirection["OUTPUT"] = 1] = "OUTPUT"; | |
})(IoDirection || (IoDirection = {})); | |
function getNodeById(graph, id) { | |
if (graph.getNodeById) { | |
return graph.getNodeById(id); | |
} | |
graph = graph; | |
return graph.nodes.find((n) => n.id === id); | |
} | |
function extendLink(link) { | |
return { | |
link: link, | |
id: link[0], | |
origin_id: link[1], | |
origin_slot: link[2], | |
target_id: link[3], | |
target_slot: link[4], | |
type: link[5], | |
}; | |
} | |
export function fixBadLinks(graph, fix = false, silent = false, logger = console) { | |
var _a, _b; | |
const patchedNodeSlots = {}; | |
const data = { | |
patchedNodes: [], | |
deletedLinks: [], | |
}; | |
async function patchNodeSlot(node, ioDir, slot, linkId, op) { | |
var _a, _b, _c; | |
patchedNodeSlots[node.id] = patchedNodeSlots[node.id] || {}; | |
const patchedNode = patchedNodeSlots[node.id]; | |
if (ioDir == IoDirection.INPUT) { | |
patchedNode["inputs"] = patchedNode["inputs"] || {}; | |
if (patchedNode["inputs"][slot] !== undefined) { | |
!silent && | |
logger.log(` > Already set ${node.id}.inputs[${slot}] to ${patchedNode["inputs"][slot]} Skipping.`); | |
return false; | |
} | |
let linkIdToSet = op === "REMOVE" ? null : linkId; | |
patchedNode["inputs"][slot] = linkIdToSet; | |
if (fix) { | |
} | |
} | |
else { | |
patchedNode["outputs"] = patchedNode["outputs"] || {}; | |
patchedNode["outputs"][slot] = patchedNode["outputs"][slot] || { | |
links: [...(((_b = (_a = node.outputs) === null || _a === void 0 ? void 0 : _a[slot]) === null || _b === void 0 ? void 0 : _b.links) || [])], | |
changes: {}, | |
}; | |
if (patchedNode["outputs"][slot]["changes"][linkId] !== undefined) { | |
!silent && | |
logger.log(` > Already set ${node.id}.outputs[${slot}] to ${patchedNode["inputs"][slot]}! Skipping.`); | |
return false; | |
} | |
patchedNode["outputs"][slot]["changes"][linkId] = op; | |
if (op === "ADD") { | |
let linkIdIndex = patchedNode["outputs"][slot]["links"].indexOf(linkId); | |
if (linkIdIndex !== -1) { | |
!silent && logger.log(` > Hmmm.. asked to add ${linkId} but it is already in list...`); | |
return false; | |
} | |
patchedNode["outputs"][slot]["links"].push(linkId); | |
if (fix) { | |
node.outputs = node.outputs || []; | |
node.outputs[slot] = node.outputs[slot] || {}; | |
node.outputs[slot].links = node.outputs[slot].links || []; | |
node.outputs[slot].links.push(linkId); | |
} | |
} | |
else { | |
let linkIdIndex = patchedNode["outputs"][slot]["links"].indexOf(linkId); | |
if (linkIdIndex === -1) { | |
!silent && logger.log(` > Hmmm.. asked to remove ${linkId} but it doesn't exist...`); | |
return false; | |
} | |
patchedNode["outputs"][slot]["links"].splice(linkIdIndex, 1); | |
if (fix) { | |
(_c = node.outputs) === null || _c === void 0 ? void 0 : _c[slot].links.splice(linkIdIndex, 1); | |
} | |
} | |
} | |
data.patchedNodes.push(node); | |
return true; | |
} | |
function nodeHasLinkId(node, ioDir, slot, linkId) { | |
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; | |
let has = false; | |
if (ioDir === IoDirection.INPUT) { | |
let nodeHasIt = ((_b = (_a = node.inputs) === null || _a === void 0 ? void 0 : _a[slot]) === null || _b === void 0 ? void 0 : _b.link) === linkId; | |
if ((_c = patchedNodeSlots[node.id]) === null || _c === void 0 ? void 0 : _c["inputs"]) { | |
let patchedHasIt = patchedNodeSlots[node.id]["inputs"][slot] === linkId; | |
if (fix && nodeHasIt !== patchedHasIt) { | |
throw Error("Error. Expected node to match patched data."); | |
} | |
has = patchedHasIt; | |
} | |
else { | |
has = !!nodeHasIt; | |
} | |
} | |
else { | |
let nodeHasIt = (_f = (_e = (_d = node.outputs) === null || _d === void 0 ? void 0 : _d[slot]) === null || _e === void 0 ? void 0 : _e.links) === null || _f === void 0 ? void 0 : _f.includes(linkId); | |
if ((_j = (_h = (_g = patchedNodeSlots[node.id]) === null || _g === void 0 ? void 0 : _g["outputs"]) === null || _h === void 0 ? void 0 : _h[slot]) === null || _j === void 0 ? void 0 : _j["changes"][linkId]) { | |
let patchedHasIt = (_k = patchedNodeSlots[node.id]["outputs"][slot]) === null || _k === void 0 ? void 0 : _k.links.includes(linkId); | |
if (fix && nodeHasIt !== patchedHasIt) { | |
throw Error("Error. Expected node to match patched data."); | |
} | |
has = !!patchedHasIt; | |
} | |
else { | |
has = !!nodeHasIt; | |
} | |
} | |
return has; | |
} | |
function nodeHasAnyLink(node, ioDir, slot) { | |
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; | |
let hasAny = false; | |
if (ioDir === IoDirection.INPUT) { | |
let nodeHasAny = ((_b = (_a = node.inputs) === null || _a === void 0 ? void 0 : _a[slot]) === null || _b === void 0 ? void 0 : _b.link) != null; | |
if ((_c = patchedNodeSlots[node.id]) === null || _c === void 0 ? void 0 : _c["inputs"]) { | |
let patchedHasAny = patchedNodeSlots[node.id]["inputs"][slot] != null; | |
if (fix && nodeHasAny !== patchedHasAny) { | |
throw Error("Error. Expected node to match patched data."); | |
} | |
hasAny = patchedHasAny; | |
} | |
else { | |
hasAny = !!nodeHasAny; | |
} | |
} | |
else { | |
let nodeHasAny = (_f = (_e = (_d = node.outputs) === null || _d === void 0 ? void 0 : _d[slot]) === null || _e === void 0 ? void 0 : _e.links) === null || _f === void 0 ? void 0 : _f.length; | |
if ((_j = (_h = (_g = patchedNodeSlots[node.id]) === null || _g === void 0 ? void 0 : _g["outputs"]) === null || _h === void 0 ? void 0 : _h[slot]) === null || _j === void 0 ? void 0 : _j["changes"]) { | |
let patchedHasAny = (_k = patchedNodeSlots[node.id]["outputs"][slot]) === null || _k === void 0 ? void 0 : _k.links.length; | |
if (fix && nodeHasAny !== patchedHasAny) { | |
throw Error("Error. Expected node to match patched data."); | |
} | |
hasAny = !!patchedHasAny; | |
} | |
else { | |
hasAny = !!nodeHasAny; | |
} | |
} | |
return hasAny; | |
} | |
let links = []; | |
if (!Array.isArray(graph.links)) { | |
Object.values(graph.links).reduce((acc, v) => { | |
acc[v.id] = v; | |
return acc; | |
}, links); | |
} | |
else { | |
links = graph.links; | |
} | |
const linksReverse = [...links]; | |
linksReverse.reverse(); | |
for (let l of linksReverse) { | |
if (!l) | |
continue; | |
const link = l.origin_slot != null ? l : extendLink(l); | |
const originNode = getNodeById(graph, link.origin_id); | |
const originHasLink = () => nodeHasLinkId(originNode, IoDirection.OUTPUT, link.origin_slot, link.id); | |
const patchOrigin = (op, id = link.id) => patchNodeSlot(originNode, IoDirection.OUTPUT, link.origin_slot, id, op); | |
const targetNode = getNodeById(graph, link.target_id); | |
const targetHasLink = () => nodeHasLinkId(targetNode, IoDirection.INPUT, link.target_slot, link.id); | |
const targetHasAnyLink = () => nodeHasAnyLink(targetNode, IoDirection.INPUT, link.target_slot); | |
const patchTarget = (op, id = link.id) => patchNodeSlot(targetNode, IoDirection.INPUT, link.target_slot, id, op); | |
const originLog = `origin(${link.origin_id}).outputs[${link.origin_slot}].links`; | |
const targetLog = `target(${link.target_id}).inputs[${link.target_slot}].link`; | |
if (!originNode || !targetNode) { | |
if (!originNode && !targetNode) { | |
!silent && | |
logger.log(`Link ${link.id} is invalid, ` + | |
`both origin ${link.origin_id} and target ${link.target_id} do not exist`); | |
} | |
else if (!originNode) { | |
!silent && | |
logger.log(`Link ${link.id} is funky... ` + | |
`origin ${link.origin_id} does not exist, but target ${link.target_id} does.`); | |
if (targetHasLink()) { | |
!silent && | |
logger.log(` > [PATCH] ${targetLog} does have link, will remove the inputs' link first.`); | |
patchTarget("REMOVE", -1); | |
} | |
} | |
else if (!targetNode) { | |
!silent && | |
logger.log(`Link ${link.id} is funky... ` + | |
`target ${link.target_id} does not exist, but origin ${link.origin_id} does.`); | |
if (originHasLink()) { | |
!silent && | |
logger.log(` > [PATCH] Origin's links' has ${link.id}; will remove the link first.`); | |
patchOrigin("REMOVE"); | |
} | |
} | |
continue; | |
} | |
if (targetHasLink() || originHasLink()) { | |
if (!originHasLink()) { | |
!silent && | |
logger.log(`${link.id} is funky... ${originLog} does NOT contain it, but ${targetLog} does.`); | |
!silent && | |
logger.log(` > [PATCH] Attempt a fix by adding this ${link.id} to ${originLog}.`); | |
patchOrigin("ADD"); | |
} | |
else if (!targetHasLink()) { | |
!silent && | |
logger.log(`${link.id} is funky... ${targetLog} is NOT correct (is ${(_b = (_a = targetNode.inputs) === null || _a === void 0 ? void 0 : _a[link.target_slot]) === null || _b === void 0 ? void 0 : _b.link}), but ${originLog} contains it`); | |
if (!targetHasAnyLink()) { | |
!silent && logger.log(` > [PATCH] ${targetLog} is not defined, will set to ${link.id}.`); | |
let patched = patchTarget("ADD"); | |
if (!patched) { | |
!silent && | |
logger.log(` > [PATCH] Nvm, ${targetLog} already patched. Removing ${link.id} from ${originLog}.`); | |
patched = patchOrigin("REMOVE"); | |
} | |
} | |
else { | |
!silent && | |
logger.log(` > [PATCH] ${targetLog} is defined, removing ${link.id} from ${originLog}.`); | |
patchOrigin("REMOVE"); | |
} | |
} | |
} | |
} | |
for (let l of linksReverse) { | |
if (!l) | |
continue; | |
const link = l.origin_slot != null ? l : extendLink(l); | |
const originNode = getNodeById(graph, link.origin_id); | |
const targetNode = getNodeById(graph, link.target_id); | |
if ((!originNode || !nodeHasLinkId(originNode, IoDirection.OUTPUT, link.origin_slot, link.id)) && | |
(!targetNode || !nodeHasLinkId(targetNode, IoDirection.INPUT, link.target_slot, link.id))) { | |
!silent && | |
logger.log(`${link.id} is def invalid; BOTH origin node ${link.origin_id} ${!originNode ? "is removed" : `doesn\'t have ${link.id}`} and ${link.origin_id} target node ${!targetNode ? "is removed" : `doesn\'t have ${link.id}`}.`); | |
data.deletedLinks.push(link.id); | |
continue; | |
} | |
} | |
if (fix) { | |
for (let i = data.deletedLinks.length - 1; i >= 0; i--) { | |
!silent && logger.log(`Deleting link #${data.deletedLinks[i]}.`); | |
if (graph.getNodeById) { | |
delete graph.links[data.deletedLinks[i]]; | |
} | |
else { | |
graph = graph; | |
const idx = graph.links.findIndex((l) => l && (l[0] === data.deletedLinks[i] || l.id === data.deletedLinks[i])); | |
if (idx === -1) { | |
logger.log(`INDEX NOT FOUND for #${data.deletedLinks[i]}`); | |
} | |
logger.log(`splicing ${idx} from links`); | |
graph.links.splice(idx, 1); | |
} | |
} | |
if (!graph.getNodeById) { | |
graph.links = graph.links.filter((l) => !!l); | |
} | |
} | |
if (!data.patchedNodes.length && !data.deletedLinks.length) { | |
return { | |
hasBadLinks: false, | |
fixed: false, | |
graph, | |
patched: data.patchedNodes.length, | |
deleted: data.deletedLinks.length, | |
}; | |
} | |
!silent && | |
logger.log(`${fix ? "Made" : "Would make"} ${data.patchedNodes.length || "no"} node link patches, and ${data.deletedLinks.length || "no"} stale link removals.`); | |
let hasBadLinks = !!(data.patchedNodes.length || data.deletedLinks.length); | |
if (fix && !silent) { | |
const rerun = fixBadLinks(graph, false, true); | |
hasBadLinks = rerun.hasBadLinks; | |
} | |
return { | |
hasBadLinks, | |
fixed: !!hasBadLinks && fix, | |
graph, | |
patched: data.patchedNodes.length, | |
deleted: data.deletedLinks.length, | |
}; | |
} | |