w4c-workflows-api/Services/Nodes/NodeGraphRunner.Shaping.cs
Vitali sharp8n 42ffcb9adc workflows
2026-09-13 19:28:47 +03:00

68 lines
2.4 KiB
C#

using System.Text.Json.Nodes;
using w4c_workflows.Models.Credentials;
using w4c_workflows.Models.Nodes;
using w4c_workflows.Services.Nodes.Interpolation;
using w4c_workflows.Services.Security;
namespace w4c_workflows.Services.Nodes;
// Result-shaping half of the graph runner: normalising the produced ports to the
// blueprint's output count, stamping provenance, allocating input ports and
// freezing the collected outputs into an immutable run result.
public sealed partial class NodeGraphRunner
{
// ------------------------------------------------------------------ shaping
private static List<IReadOnlyList<FlowItem>> StampAndNormalize(
IReadOnlyList<IReadOnlyList<FlowItem>> produced,
NodeGraphNode node,
int runIndex)
{
var portCount = Math.Max(1, node.Blueprint.Outputs.Count);
var ports = new List<IReadOnlyList<FlowItem>>(portCount);
for (var port = 0; port < portCount; port++)
{
var items = port < produced.Count ? produced[port] : Array.Empty<FlowItem>();
var stamped = new List<FlowItem>(items.Count);
for (var index = 0; index < items.Count; index++)
{
var item = items[index];
stamped.Add(item.Origin == null
? item with { Origin = new FlowItemOrigin(node.Id, port, runIndex, index) }
: item);
}
ports.Add(stamped);
}
return ports;
}
private static List<FlowItem>[] NewInputPorts(NodeGraphNode node)
{
var ports = new List<FlowItem>[Math.Max(1, node.Blueprint.Inputs.Count)];
for (var i = 0; i < ports.Length; i++)
ports[i] = new List<FlowItem>();
return ports;
}
private static IReadOnlyDictionary<string, IReadOnlyList<IReadOnlyList<FlowItem>>> Freeze(
IReadOnlyDictionary<string, List<IReadOnlyList<FlowItem>>> outputs)
=> outputs.ToDictionary(
pair => pair.Key,
pair => (IReadOnlyList<IReadOnlyList<FlowItem>>)pair.Value,
StringComparer.Ordinal);
private static NodeGraphRunResult Failure(
IReadOnlyDictionary<string, List<IReadOnlyList<FlowItem>>> outputs,
IReadOnlyList<string> order,
NodeFailure failure)
=> new()
{
OutputsByNode = Freeze(outputs),
ExecutionOrder = order.ToList(),
Failure = failure,
};
}