(items: Set<Positionable>)
| 1398 | } |
| 1399 | |
| 1400 | convertToSubgraph(items: Set<Positionable>): { subgraph: Subgraph, node: SubgraphNode } { |
| 1401 | if (items.size === 0) throw new Error("Cannot convert to subgraph: nothing to convert") |
| 1402 | const { state, revision, config } = this |
| 1403 | |
| 1404 | const { boundaryLinks, boundaryFloatingLinks, internalLinks, boundaryInputLinks, boundaryOutputLinks } = getBoundaryLinks(this, items) |
| 1405 | const { nodes, reroutes, groups } = splitPositionables(items) |
| 1406 | |
| 1407 | const boundingRect = createBounds(items) |
| 1408 | if (!boundingRect) throw new Error("Failed to create bounding rect for subgraph") |
| 1409 | |
| 1410 | const resolvedInputLinks = boundaryInputLinks.map(x => x.resolve(this)) |
| 1411 | const resolvedOutputLinks = boundaryOutputLinks.map(x => x.resolve(this)) |
| 1412 | |
| 1413 | const clonedNodes = multiClone(nodes) |
| 1414 | |
| 1415 | // Inputs, outputs, and links |
| 1416 | const links = internalLinks.map(x => x.asSerialisable()) |
| 1417 | const inputs = mapSubgraphInputsAndLinks(resolvedInputLinks, links) |
| 1418 | const outputs = mapSubgraphOutputsAndLinks(resolvedOutputLinks, links) |
| 1419 | |
| 1420 | // Prepare subgraph data |
| 1421 | const data = { |
| 1422 | id: createUuidv4(), |
| 1423 | name: "New Subgraph", |
| 1424 | inputNode: { |
| 1425 | id: SUBGRAPH_INPUT_ID, |
| 1426 | bounding: [0, 0, 75, 100], |
| 1427 | }, |
| 1428 | outputNode: { |
| 1429 | id: SUBGRAPH_OUTPUT_ID, |
| 1430 | bounding: [0, 0, 75, 100], |
| 1431 | }, |
| 1432 | inputs, |
| 1433 | outputs, |
| 1434 | widgets: [], |
| 1435 | version: LGraph.serialisedSchemaVersion, |
| 1436 | state, |
| 1437 | revision, |
| 1438 | config, |
| 1439 | links, |
| 1440 | nodes: clonedNodes, |
| 1441 | reroutes: structuredClone([...reroutes].map(reroute => reroute.asSerialisable())), |
| 1442 | groups: structuredClone([...groups].map(group => group.serialize())), |
| 1443 | } satisfies ExportedSubgraph |
| 1444 | |
| 1445 | const subgraph = this.createSubgraph(data) |
| 1446 | subgraph.configure(data) |
| 1447 | |
| 1448 | // Position the subgraph input nodes |
| 1449 | subgraph.inputNode.arrange() |
| 1450 | subgraph.outputNode.arrange() |
| 1451 | const { boundingRect: inputRect } = subgraph.inputNode |
| 1452 | const { boundingRect: outputRect } = subgraph.outputNode |
| 1453 | alignOutsideContainer(inputRect, Alignment.MidLeft, boundingRect, [50, 0]) |
| 1454 | alignOutsideContainer(outputRect, Alignment.MidRight, boundingRect, [50, 0]) |
| 1455 | |
| 1456 | // Remove items converted to subgraph |
| 1457 | for (const resolved of resolvedInputLinks) resolved.inputNode?.disconnectInput(resolved.inputNode.inputs.indexOf(resolved.input!), true) |
no test coverage detected