# `Runic.Workflow.Connection`
[🔗](https://github.com/zblanco/runic/blob/main/lib/workflow/connection.ex#L1)

A durable named-port connection between two workflow components.

Connections describe authored intent. `Runic.Workflow.add/3` validates a
complete connection group and lowers it into executable flow nodes. The
connection itself remains data and is stored on logical `:connects_to` edges
and in `%Runic.Workflow.ComponentAdded{}` events.

The compact keyword form accepted by `Runic.Workflow.add/3` is normalized
into this struct. The component being added supplies the target component:

    [from: {:orders, :order}, to: :order]

`:from` identifies `{source_component, source_port}` and `:to` identifies the
target input port. The long source form is also accepted:

    [from: :orders, source_port: :order, to: :order]

## Projection and assembly

`:selector` reads a path from the selected source value. `:target_path`
places that value inside a structure assembled for the target port:

    [
      id: "customer-id",
      from: {:orders, :payload},
      to: :request,
      selector: [:customer, :id],
      target_path: [:customer_id]
    ]

A source with one declared output treats that port as the complete produced
value. A source with several outputs exposes values by map or keyword key, or
by tuple/list position. The target's declared input-port order, not connection
declaration order, determines positional arguments for multi-arity steps.

Safe `:selector` and `:target_path` lists may contain atom, string, or
non-negative integer segments. They never contain executable functions.
Target paths assigned within one connection group must not overlap.

`:id` is optional in the keyword form. If omitted, Runic derives a stable ID
from the normalized connection data. Authored IDs may be atoms, strings, or
non-negative integers.

See the [Cheatsheet](cheatsheet.html#named-port-connections) and
[Usage Rules](usage-rules.html#prefer-connections-for-data-binding) for full
construction examples and API-selection guidance.

# `component_ref`

```elixir
@type component_ref() ::
  atom() | String.t() | non_neg_integer() | {atom() | String.t(), atom()}
```

# `connection_id`

```elixir
@type connection_id() :: atom() | String.t() | non_neg_integer() | Runic.Identity.t()
```

# `path_segment`

```elixir
@type path_segment() :: atom() | String.t() | non_neg_integer()
```

# `port_name`

```elixir
@type port_name() :: atom()
```

# `t`

```elixir
@type t() :: %Runic.Workflow.Connection{
  id: connection_id(),
  selector: [path_segment()],
  source: component_ref(),
  source_port: port_name(),
  target: component_ref(),
  target_path: [path_segment()],
  target_port: port_name()
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
