Choreo.Sequence (Choreo v0.8.0)

Copy Markdown View Source

Sequence diagrams for Choreo.

Sequence diagrams show how participants interact with each other over time. Unlike most other Choreo modules, this module is heavily skewed toward Mermaid's native sequenceDiagram syntax — GraphViz has no native sequence-diagram concept, so the DOT renderer is provided as a best-effort timeline-style fallback.

Supported features

  • Participants and Actors (external roles)
  • Synchronous, asynchronous, return, and self messages
  • Activation boxes (activate / deactivate)
  • Notes (over, left, right of a participant, or between two)
  • Loops and fragments (loop, opt, alt/else, par, break, critical)

Example

iex> alias Choreo.Sequence
iex> Sequence.new()
...> |> Sequence.add_actor(:user, label: "User")
...> |> Sequence.add_participant(:api, label: "API")
...> |> Sequence.add_participant(:db, label: "Database")
...> |> Sequence.message(:user, :api, label: "GET /accounts")
...> |> Sequence.activate(:api)
...> |> Sequence.message(:api, :db, label: "SELECT * FROM accounts")
...> |> Sequence.return(:db, :api, label: "rows")
...> |> Sequence.deactivate(:api)
...> |> Sequence.return(:api, :user, label: "200 OK")
...> |> Sequence.to_mermaid()
...> |> String.split("\n")
...> |> Enum.take(4)
["sequenceDiagram", "    actor User", "    participant API", "    participant Database"]

Summary

Functions

Emits an activate event for the given participant.

Adds an actor (external person or system) to the diagram.

Adds a participant to the diagram.

Adds an asynchronous message.

Emits a deactivate event for the given participant.

Ends the most recently started fragment.

Returns all ordered events in the diagram.

Starts a fragment (loop, opt, alt, par, break, critical).

Adds a message from from to to.

Returns messages in chronological order.

Creates a new empty sequence diagram.

Adds a note to the diagram.

Returns metadata for a participant.

Returns all participants/actors in the diagram.

Adds a return message.

Adds a self-message on the given participant.

Renders the diagram as a DOT graph (best-effort timeline view).

Renders the diagram as a Mermaid sequence diagram.

Types

event_type()

@type event_type() :: :message | :activation | :note | :fragment

fragment_kind()

@type fragment_kind() :: :loop | :opt | :alt | :else | :par | :break | :critical

message_type()

@type message_type() :: :sync | :async | :return | :self

note_position()

@type note_position() ::
  {:over, atom()}
  | {:left, atom()}
  | {:right, atom()}
  | {:between, atom(), atom()}

t()

@type t() :: %Choreo.Sequence{
  edge_meta: term(),
  events: term(),
  graph: term(),
  next_order: term(),
  participants: term()
}

Functions

activate(seq, participant)

@spec activate(t(), atom()) :: t()

Emits an activate event for the given participant.

add_actor(seq, id, opts \\ [])

@spec add_actor(t(), atom(), keyword()) :: t()

Adds an actor (external person or system) to the diagram.

Options

  • :label - display name (defaults to Macro.camelize/1 of the id)
  • :description - longer description (used by analysis, not rendered)

add_participant(seq, id, opts \\ [])

@spec add_participant(t(), atom(), keyword()) :: t()

Adds a participant to the diagram.

Options

  • :label - display name
  • :description - longer description

async(seq, from, to, opts \\ [])

@spec async(t(), atom(), atom(), keyword()) :: t()

Adds an asynchronous message.

deactivate(seq, participant)

@spec deactivate(t(), atom()) :: t()

Emits a deactivate event for the given participant.

end_fragment(seq)

@spec end_fragment(t()) :: t()

Ends the most recently started fragment.

events(sequence)

@spec events(t()) :: [map()]

Returns all ordered events in the diagram.

fragment(seq, kind, label \\ nil)

@spec fragment(t(), fragment_kind(), String.t() | nil) :: t()

Starts a fragment (loop, opt, alt, par, break, critical).

Examples

seq
|> Sequence.fragment(:loop, "for each item")
|> Sequence.message(:a, :b, label: "process")
|> Sequence.end_fragment()

seq
|> Sequence.fragment(:alt, "x > 0")
|> Sequence.message(:a, :b, label: "positive")
|> Sequence.fragment(:else, "otherwise")
|> Sequence.message(:a, :b, label: "negative")
|> Sequence.end_fragment()

message(seq, from, to, opts \\ [])

@spec message(t(), atom(), atom(), keyword()) :: t()

Adds a message from from to to.

Options

  • :label - message label
  • :type - :sync (default), :async, :return, or :self

A self-message is automatically detected when from == to.

messages(seq)

@spec messages(t()) :: [map()]

Returns messages in chronological order.

new()

@spec new() :: t()

Creates a new empty sequence diagram.

note(seq, position, text)

@spec note(t(), note_position(), String.t()) :: t()

Adds a note to the diagram.

position can be:

  • {:over, :alice}
  • {:left, :alice}
  • {:right, :alice}
  • {:between, :alice, :bob}

participant(sequence, id)

@spec participant(t(), atom()) :: map() | nil

Returns metadata for a participant.

participants(sequence)

@spec participants(t()) :: [atom()]

Returns all participants/actors in the diagram.

return(seq, from, to, opts \\ [])

@spec return(t(), atom(), atom(), keyword()) :: t()

Adds a return message.

self_message(seq, participant, opts \\ [])

@spec self_message(t(), atom(), keyword()) :: t()

Adds a self-message on the given participant.

to_dot(seq, opts \\ [])

@spec to_dot(
  t(),
  keyword()
) :: String.t()

Renders the diagram as a DOT graph (best-effort timeline view).

to_mermaid(seq, opts \\ [])

@spec to_mermaid(
  t(),
  keyword()
) :: String.t()

Renders the diagram as a Mermaid sequence diagram.