Spaces:
Running
on
Zero
Running
on
Zero
import { app } from "../../../scripts/app.js"; | |
const REPEATER = "Repeater|pysssss"; | |
app.registerExtension({ | |
name: "pysssss.Repeater", | |
init() { | |
const graphToPrompt = app.graphToPrompt; | |
app.graphToPrompt = async function () { | |
const res = await graphToPrompt.apply(this, arguments); | |
const id = Date.now() + "_"; | |
let u = 0; | |
let newNodes = {}; | |
const newRepeaters = {}; | |
for (const nodeId in res.output) { | |
let output = res.output[nodeId]; | |
if (output.class_type === REPEATER) { | |
const isMulti = output.inputs.output === "multi"; | |
if (output.inputs.node_mode === "create") { | |
// We need to clone the input for every repeat | |
const orig = res.output[output.inputs.source[0]]; | |
if (isMulti) { | |
if (!newRepeaters[nodeId]) { | |
newRepeaters[nodeId] = []; | |
newRepeaters[nodeId][output.inputs.repeats - 1] = nodeId; | |
} | |
} | |
for (let i = 0; i < output.inputs.repeats - 1; i++) { | |
const clonedInputId = id + ++u; | |
if (isMulti) { | |
// If multi create we need to clone the repeater too | |
newNodes[clonedInputId] = structuredClone(orig); | |
output = structuredClone(output); | |
const clonedRepeaterId = id + ++u; | |
newNodes[clonedRepeaterId] = output; | |
output.inputs["source"][0] = clonedInputId; | |
newRepeaters[nodeId][i] = clonedRepeaterId; | |
} else { | |
newNodes[clonedInputId] = orig; | |
} | |
output.inputs[clonedInputId] = [clonedInputId, output.inputs.source[1]]; | |
} | |
} else if (isMulti) { | |
newRepeaters[nodeId] = Array(output.inputs.repeats).fill(nodeId); | |
} | |
} | |
} | |
Object.assign(res.output, newNodes); | |
newNodes = {}; | |
for (const nodeId in res.output) { | |
const output = res.output[nodeId]; | |
for (const k in output.inputs) { | |
const v = output.inputs[k]; | |
if (v instanceof Array) { | |
const repeaterId = v[0]; | |
const source = newRepeaters[repeaterId]; | |
if (source) { | |
v[0] = source.pop(); | |
v[1] = 0; | |
} | |
} | |
} | |
} | |
// Object.assign(res.output, newNodes); | |
return res; | |
}; | |
}, | |
beforeRegisterNodeDef(nodeType, nodeData, app) { | |
if (nodeData.name === REPEATER) { | |
const SETUP_OUTPUTS = Symbol(); | |
nodeType.prototype[SETUP_OUTPUTS] = function (repeats) { | |
if (repeats == null) { | |
repeats = this.widgets[0].value; | |
} | |
while (this.outputs.length > repeats) { | |
this.removeOutput(repeats); | |
} | |
const id = Date.now() + "_"; | |
let u = 0; | |
while (this.outputs.length < repeats) { | |
this.addOutput(id + ++u, "*", { label: "*" }); | |
} | |
}; | |
const onAdded = nodeType.prototype.onAdded; | |
nodeType.prototype.onAdded = function () { | |
const self = this; | |
const repeatsCb = this.widgets[0].callback; | |
this.widgets[0].callback = async function () { | |
const v = (await repeatsCb?.apply(this, arguments)) ?? this.value; | |
if (self.widgets[1].value === "multi") { | |
self[SETUP_OUTPUTS](v); | |
} | |
return v; | |
}; | |
const outputCb = this.widgets[1].callback; | |
this.widgets[1].callback = async function () { | |
const v = (await outputCb?.apply(this, arguments)) ?? this.value; | |
if (v === "single") { | |
self.outputs[0].shape = 6; | |
self[SETUP_OUTPUTS](1); | |
} else { | |
delete self.outputs[0].shape; | |
self[SETUP_OUTPUTS](); | |
} | |
return v; | |
}; | |
return onAdded?.apply(this, arguments); | |
}; | |
} | |
}, | |
}); | |