# Ports and validation

Ports are the connection points on a node. Their side, direction, data type, and
capacity describe the connections the graph can make.

## How the pieces fit together

For a domain graph, declare ports on the node. `side` places the port, `type`
sets whether it starts or ends a link, and `dataType` gives it a named data-flow
type. `shape` and `label` change its visible glyph and caption. Use
`maxConnections` for a simple cap; use `gating` when the rule also needs
directional connectability, allowed types, or self-link policy.

```ts
const nodes = [
  {
    id: 'transform',
    position: { x: 80, y: 120 },
    size: { width: 180, height: 100 },
    label: 'Transform',
    ports: [
      { id: 'in', side: 'left', type: 'input', dataType: 'frame' },
      { id: 'out', side: 'right', type: 'output', dataType: 'frame' },
      {
        id: 'errors',
        side: 'bottom',
        type: 'output',
        maxConnections: 1,
        shape: { shape: 'diamond', size: 12 },
        label: { text: 'errors', layout: 'outside' },
      },
    ],
  },
];
```

The port glyphs appear on hover by default. Set the interaction option to
`portVisibility: 'always'` when the diagram needs to expose every connection
point continuously.

## Use data types for declarative compatibility

Register the data types once at application bootstrap with
[`portTypeRegistry`](https://atloria.dev/p/grafloria-h7YM7amryF/developer/grafloria-engine-ports#porttyperegistry). A type may
list additional compatible types in `compatibleWith`; an exact name also
matches. Its `color` controls the port glyph colour.

```ts
import { portTypeRegistry } from '@grafloria/element';

portTypeRegistry.registerAll([
  { name: 'number', color: '#2563eb', compatibleWith: ['number'] },
  { name: 'string', color: '#9333ea', compatibleWith: ['string'] },
]);
```

A `number` output can therefore connect to a `number` input, while a
`number`-to-`string` attempt is refused during the drag. The matching port is
highlighted as a valid target, and the mismatched port is not; no link is
created for the refused attempt.

The same node and edge specs work in the Qwik binding through
[`GrafloriaFlow`](https://atloria.dev/p/grafloria-h7YM7amryF/developer/grafloria-qwik#grafloriaflow). Give the component's
host a resolved height so the mounted canvas has visible space:

```tsx
import { component$ } from '@builder.io/qwik';
import { GrafloriaFlow, type EdgeSpec, type NodeSpec } from '@grafloria/qwik';

const nodes: NodeSpec[] = [
  {
    id: 'source',
    position: { x: 80, y: 100 },
    size: { width: 150, height: 70 },
    label: 'Source',
    ports: [{ id: 'out', side: 'right', type: 'output', dataType: 'number' }],
  },
  {
    id: 'sink',
    position: { x: 360, y: 100 },
    size: { width: 150, height: 70 },
    label: 'Sink',
    ports: [{ id: 'in', side: 'left', type: 'input', dataType: 'number' }],
  },
];

const edges: EdgeSpec[] = [];

export default component$(() => (
  <div style="height: 360px">
    <GrafloriaFlow
      nodes={nodes}
      edges={edges}
      interaction={{ portVisibility: 'always' }}
    />
  </div>
));
```

This component renders the same two typed ports as the element example. Its
`number` output can connect to its `number` input after the type is registered.

## See it running

The [typed ports demo](https://grafloria.com/demos/ports/typed-ports.html) shows
blue number ports, a purple string port, an accepted number-to-number link, and
a refused number-to-string drag.

The live demo shows the number ports in blue and the string port in purple;
the accepted number-to-number wire remains visible while the mismatched drag
is refused.

For a broader connection rule, see [Validate connections](https://atloria.dev/p/grafloria-h7YM7amryF/developer/validate-connections).
For edge endpoint and routing details, see [Edit and route edges](https://atloria.dev/p/grafloria-h7YM7amryF/developer/edit-and-route-edges).
For the model objects behind the rendered ports, see [Model and document](https://atloria.dev/p/grafloria-h7YM7amryF/developer/model-and-document).
