(node: NodeData)
| 157 | * Get a flat arguments record for any node instance. Used to feed parameter |
| 158 | * resolution (FromArgs<T> lambdas, activation rules). Output bindings live in |
| 159 | * the same record under their own (non-colliding) output ids — lambdas address |
| 160 | * parameters by parameter id and never hit them accidentally. |
| 161 | */ |
| 162 | export function getArguments(node: NodeData): Record<string, unknown> { |
| 163 | return node.arguments as Record<string, unknown>; |
| 164 | } |
| 165 | |
| 166 | /** |
| 167 | * Compute the outputs the node currently can produce (before binding decisions). |
| 168 | * For FunctionCall: derived from the per-instance functionInfo snapshot (decoupled from live function defs). |
| 169 | * For all others: derived from the registered NodeDefinition's outputs[] + the node's current arguments. |
| 170 | * |
| 171 | * List outputs: only emit-mode entries are surfaced. Assign-mode entries route to |
| 172 | * existing variables and don't create new output slots in scope — they're validated |
| 173 | * as bindings, not reported as available outputs. |
| 174 | */ |
| 175 | export function getNodeAvailableOutput(node: NodeData): Record<string, NodeOutput> { |
| 176 | const result: Record<string, NodeOutput> = {}; |
| 177 | |
| 178 | if (node.type === "FunctionCall") { |
| 179 | for (const ret of node.functionInfo.returns) { |
| 180 | result[ret.uid] = { name: ret.name, dataType: ret.dataType }; |
| 181 | } |
| 182 | return result; |
| 183 | } |
| 184 | |
| 185 | const def = NodeRegistry.getByType(node.type); |
| 186 | if (!def?.outputs) return result; |
| 187 | |
| 188 | const args = node.arguments as Record<string, unknown>; |
| 189 | for (const out of def.outputs) { |
| 190 | if (out.type === "static") { |
| 191 | result[out.id] = { |
| 192 | name: out.id, |
no test coverage detected