comfy-workflow
Advanced tools
Comparing version 0.2.0 to 0.3.0
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Graph = exports.GraphGroup = exports.GraphNode = exports.NodeOutputSlot = exports.NodeInputSlot = exports.NodeSlot = exports.GraphLink = void 0; | ||
const _1 = require("."); | ||
const graph_json_1 = require("./graph-json"); | ||
@@ -45,3 +46,3 @@ class GraphLink { | ||
class GraphNode { | ||
constructor(graph, id, type, pos, size, flags, order, mode, inputs = [], outputs = [], properties = {}, widgets_values = []) { | ||
constructor(graph, id, type, pos = [0, 0], size = [0, 0], flags = {}, order = 0, mode = 0, inputs = [], outputs = [], properties = {}, widgets_values = []) { | ||
this.graph = graph; | ||
@@ -90,2 +91,39 @@ this.id = id; | ||
} | ||
findOutputSlot(name, returnObj = false) { | ||
if (!this.outputs) { | ||
return -1; | ||
} | ||
for (const [i, output] of this.outputs.entries()) { | ||
if (name === output.name) { | ||
return !returnObj ? i : output; | ||
} | ||
} | ||
return -1; | ||
} | ||
connect(slot, targetNode, targetSlot = 0) { | ||
if (!this.outputs || slot >= this.outputs.length) { | ||
return null; | ||
} | ||
if (targetNode === this) { | ||
return null; | ||
} | ||
const input = targetNode.inputs[targetSlot]; | ||
if (!input) | ||
return null; | ||
const output = this.outputs[slot]; | ||
if (!output) | ||
return null; | ||
if (targetNode.inputs[targetSlot].link != null) { | ||
targetNode.inputs[targetSlot].link = null; | ||
} | ||
const nextId = ++this.graph.lastLinkId; | ||
const link = new GraphLink(nextId, input.type || output.type, this.id, slot, targetNode.id, targetSlot); | ||
this.graph.links.set(link.id, link); | ||
if (output.links == null) { | ||
output.links = []; | ||
} | ||
output.links.push(link.id); | ||
targetNode.inputs[targetSlot].link = link.id; | ||
return link; | ||
} | ||
} | ||
@@ -105,2 +143,4 @@ exports.GraphNode = GraphNode; | ||
constructor() { | ||
this.lastNodeId = 0; | ||
this.lastLinkId = 0; | ||
this.nodes = {}; | ||
@@ -114,4 +154,4 @@ this.links = new Map(); | ||
clear() { | ||
this.lastNodeId = undefined; | ||
this.lastLinkId = undefined; | ||
this.lastNodeId = 0; | ||
this.lastLinkId = 0; | ||
this.nodes = {}; | ||
@@ -273,4 +313,25 @@ this.links = new Map(); | ||
} | ||
static fromWorkflow(workflow) { | ||
const graph = new Graph(); | ||
for (const [id, data] of Object.entries(workflow)) { | ||
graph.nodes[id] = new GraphNode(graph, id, data.class_type); | ||
} | ||
for (const [id, node] of Object.entries(graph.nodes)) { | ||
const data = workflow[id]; | ||
for (const input in data.inputs ?? {}) { | ||
const value = data.inputs[input]; | ||
if (_1.APIFormat.isOutput(value)) { | ||
const [fromId, fromSlot] = value; | ||
const fromNode = graph.getNodeById(fromId); | ||
const toSlot = node.inputs?.findIndex(inp => inp.name === input); | ||
if (toSlot != null || toSlot !== -1) { | ||
fromNode.connect(fromSlot, node, toSlot); | ||
} | ||
} | ||
} | ||
} | ||
return graph; | ||
} | ||
} | ||
exports.Graph = Graph; | ||
//# sourceMappingURL=graph.js.map |
@@ -0,1 +1,2 @@ | ||
import { APIFormat } from '.'; | ||
import { zComfyWorkflow } from './graph-json'; | ||
@@ -38,3 +39,3 @@ export class GraphLink { | ||
export class GraphNode { | ||
constructor(graph, id, type, pos, size, flags, order, mode, inputs = [], outputs = [], properties = {}, widgets_values = []) { | ||
constructor(graph, id, type, pos = [0, 0], size = [0, 0], flags = {}, order = 0, mode = 0, inputs = [], outputs = [], properties = {}, widgets_values = []) { | ||
this.graph = graph; | ||
@@ -83,2 +84,39 @@ this.id = id; | ||
} | ||
findOutputSlot(name, returnObj = false) { | ||
if (!this.outputs) { | ||
return -1; | ||
} | ||
for (const [i, output] of this.outputs.entries()) { | ||
if (name === output.name) { | ||
return !returnObj ? i : output; | ||
} | ||
} | ||
return -1; | ||
} | ||
connect(slot, targetNode, targetSlot = 0) { | ||
if (!this.outputs || slot >= this.outputs.length) { | ||
return null; | ||
} | ||
if (targetNode === this) { | ||
return null; | ||
} | ||
const input = targetNode.inputs[targetSlot]; | ||
if (!input) | ||
return null; | ||
const output = this.outputs[slot]; | ||
if (!output) | ||
return null; | ||
if (targetNode.inputs[targetSlot].link != null) { | ||
targetNode.inputs[targetSlot].link = null; | ||
} | ||
const nextId = ++this.graph.lastLinkId; | ||
const link = new GraphLink(nextId, input.type || output.type, this.id, slot, targetNode.id, targetSlot); | ||
this.graph.links.set(link.id, link); | ||
if (output.links == null) { | ||
output.links = []; | ||
} | ||
output.links.push(link.id); | ||
targetNode.inputs[targetSlot].link = link.id; | ||
return link; | ||
} | ||
} | ||
@@ -96,2 +134,4 @@ export class GraphGroup { | ||
constructor() { | ||
this.lastNodeId = 0; | ||
this.lastLinkId = 0; | ||
this.nodes = {}; | ||
@@ -105,4 +145,4 @@ this.links = new Map(); | ||
clear() { | ||
this.lastNodeId = undefined; | ||
this.lastLinkId = undefined; | ||
this.lastNodeId = 0; | ||
this.lastLinkId = 0; | ||
this.nodes = {}; | ||
@@ -264,3 +304,24 @@ this.links = new Map(); | ||
} | ||
static fromWorkflow(workflow) { | ||
const graph = new Graph(); | ||
for (const [id, data] of Object.entries(workflow)) { | ||
graph.nodes[id] = new GraphNode(graph, id, data.class_type); | ||
} | ||
for (const [id, node] of Object.entries(graph.nodes)) { | ||
const data = workflow[id]; | ||
for (const input in data.inputs ?? {}) { | ||
const value = data.inputs[input]; | ||
if (APIFormat.isOutput(value)) { | ||
const [fromId, fromSlot] = value; | ||
const fromNode = graph.getNodeById(fromId); | ||
const toSlot = node.inputs?.findIndex(inp => inp.name === input); | ||
if (toSlot != null || toSlot !== -1) { | ||
fromNode.connect(fromSlot, node, toSlot); | ||
} | ||
} | ||
} | ||
} | ||
return graph; | ||
} | ||
} | ||
//# sourceMappingURL=graph.js.map |
{ | ||
"name": "comfy-workflow", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"main": "dist/cjs/index.js", | ||
@@ -5,0 +5,0 @@ "module": "dist/esm/index.js", |
108
src/graph.ts
@@ -1,2 +0,2 @@ | ||
import type { APIFormat } from '.' | ||
import { APIFormat } from '.' | ||
import { type ComfyNode, zComfyWorkflow } from './graph-json' | ||
@@ -22,3 +22,3 @@ | ||
public name: string, | ||
public type: string | -1, | ||
public type: string, | ||
public rest: object = {}, | ||
@@ -31,3 +31,3 @@ ) {} | ||
public name: string, | ||
public type: string | -1, | ||
public type: string, | ||
public link: number | null, | ||
@@ -43,3 +43,3 @@ public extra: object = {}, | ||
public name: string, | ||
public type: string | -1, | ||
public type: string, | ||
public links: number[] | null, | ||
@@ -57,7 +57,7 @@ public extra: object = {}, | ||
public type: string, | ||
public pos: Vector2, | ||
public size: Vector2, | ||
public flags: object, | ||
public order: number, | ||
public mode: number, | ||
public pos: Vector2 = [0, 0], | ||
public size: Vector2 = [0, 0], | ||
public flags: object = {}, | ||
public order = 0, | ||
public mode = 0, | ||
public inputs: NodeInputSlot[] = [], | ||
@@ -110,2 +110,61 @@ public outputs: NodeOutputSlot[] = [], | ||
} | ||
findOutputSlot(name: string): number | ||
findOutputSlot(name: string, returnObj: true): NodeOutputSlot | ||
findOutputSlot(name: string, returnObj = false) { | ||
if (!this.outputs) { | ||
return -1 | ||
} | ||
for (const [i, output] of this.outputs.entries()) { | ||
if (name === output.name) { | ||
return !returnObj ? i : output | ||
} | ||
} | ||
return -1 | ||
} | ||
connect(slot: number, targetNode: GraphNode, targetSlot = 0) { | ||
if (!this.outputs || slot >= this.outputs.length) { | ||
return null | ||
} | ||
// avoid loopback | ||
if (targetNode === this) { | ||
return null | ||
} | ||
const input = targetNode.inputs[targetSlot] | ||
if (!input) return null | ||
const output = this.outputs[slot] | ||
if (!output) return null | ||
// if there is something already plugged there, disconnect | ||
if (targetNode.inputs[targetSlot].link != null) { | ||
targetNode.inputs[targetSlot].link = null | ||
} | ||
const nextId = ++this.graph.lastLinkId | ||
// create link class | ||
const link = new GraphLink( | ||
nextId, | ||
input.type || output.type, | ||
this.id, | ||
slot, | ||
targetNode.id, | ||
targetSlot, | ||
) | ||
// add to graph links list | ||
this.graph.links.set(link.id, link) | ||
// connect in output | ||
if (output.links == null) { | ||
output.links = [] | ||
} | ||
output.links.push(link.id) | ||
// connect in input | ||
targetNode.inputs[targetSlot].link = link.id | ||
return link | ||
} | ||
} | ||
@@ -124,4 +183,4 @@ | ||
export class Graph { | ||
public lastNodeId?: ID | ||
public lastLinkId?: number | ||
public lastNodeId: ID = 0 | ||
public lastLinkId = 0 | ||
public nodes: Record<ID, GraphNode> = {} | ||
@@ -135,4 +194,4 @@ public links: Map<number, GraphLink> = new Map() | ||
clear() { | ||
this.lastNodeId = undefined | ||
this.lastLinkId = undefined | ||
this.lastNodeId = 0 | ||
this.lastLinkId = 0 | ||
this.nodes = {} | ||
@@ -356,2 +415,25 @@ this.links = new Map() | ||
} | ||
static fromWorkflow(workflow: APIFormat.Workflow) { | ||
const graph = new Graph() | ||
for (const [id, data] of Object.entries(workflow)) { | ||
graph.nodes[id] = new GraphNode(graph, id, data.class_type) | ||
} | ||
for (const [id, node] of Object.entries(graph.nodes)) { | ||
const data = workflow[id] | ||
for (const input in data.inputs ?? {}) { | ||
const value = data.inputs[input] | ||
if (APIFormat.isOutput(value)) { | ||
const [fromId, fromSlot] = value | ||
const fromNode = graph.getNodeById(fromId) | ||
const toSlot = node.inputs?.findIndex(inp => inp.name === input) | ||
if (toSlot != null || toSlot !== -1) { | ||
fromNode.connect(fromSlot, node, toSlot) | ||
} | ||
} | ||
} | ||
} | ||
return graph | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import type { APIFormat } from '.'; | ||
import { APIFormat } from '.'; | ||
import { type ComfyNode } from './graph-json'; | ||
@@ -17,19 +17,19 @@ export type ID = string | number; | ||
name: string; | ||
type: string | -1; | ||
type: string; | ||
rest: object; | ||
constructor(name: string, type: string | -1, rest?: object); | ||
constructor(name: string, type: string, rest?: object); | ||
} | ||
export declare class NodeInputSlot extends NodeSlot { | ||
name: string; | ||
type: string | -1; | ||
type: string; | ||
link: number | null; | ||
extra: object; | ||
constructor(name: string, type: string | -1, link: number | null, extra?: object); | ||
constructor(name: string, type: string, link: number | null, extra?: object); | ||
} | ||
export declare class NodeOutputSlot extends NodeSlot { | ||
name: string; | ||
type: string | -1; | ||
type: string; | ||
links: number[] | null; | ||
extra: object; | ||
constructor(name: string, type: string | -1, links: number[] | null, extra?: object); | ||
constructor(name: string, type: string, links: number[] | null, extra?: object); | ||
} | ||
@@ -49,6 +49,9 @@ export declare class GraphNode { | ||
widgets_values: unknown[]; | ||
constructor(graph: Graph, id: ID, type: string, pos: Vector2, size: Vector2, flags: object, order: number, mode: number, inputs?: NodeInputSlot[], outputs?: NodeOutputSlot[], properties?: object, widgets_values?: unknown[]); | ||
constructor(graph: Graph, id: ID, type: string, pos?: Vector2, size?: Vector2, flags?: object, order?: number, mode?: number, inputs?: NodeInputSlot[], outputs?: NodeOutputSlot[], properties?: object, widgets_values?: unknown[]); | ||
static fromJSON(graph: Graph, node: ComfyNode): GraphNode; | ||
getInputNode(slot: number): GraphNode | null; | ||
getInputLink(slot: number): GraphLink | null | undefined; | ||
findOutputSlot(name: string): number; | ||
findOutputSlot(name: string, returnObj: true): NodeOutputSlot; | ||
connect(slot: number, targetNode: GraphNode, targetSlot?: number): GraphLink | null; | ||
} | ||
@@ -64,4 +67,4 @@ export declare class GraphGroup { | ||
export declare class Graph { | ||
lastNodeId?: ID; | ||
lastLinkId?: number; | ||
lastNodeId: ID; | ||
lastLinkId: number; | ||
nodes: Record<ID, GraphNode>; | ||
@@ -80,2 +83,3 @@ links: Map<number, GraphLink>; | ||
bypassNodeById(nodeId: ID, bypass?: boolean): void; | ||
static fromWorkflow(workflow: APIFormat.Workflow): Graph; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
213195
4346
0