# `Chronicle`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle.ex#L4)

Idiomatic Elixir client for the Chronicle event-sourcing platform.

Chronicle is an event-sourcing kernel that stores domain events and projects
them into read models. This library provides an idiomatic Elixir interface
built on top of the Chronicle gRPC API.

## Quick Start

Add the dependency to your `mix.exs`:

    {:chronicle, "~> 0.1", organization: "cratis"}

Start `Chronicle.Client` in your application supervision tree:

    defmodule MyApp.Application do
      use Application

      def start(_type, _args) do
        children = [
          {Chronicle.Client,
            connection_string: "chronicle://localhost:35000?disableTls=true",
            event_store: "my-app",
            event_types: [MyApp.Events.AccountOpened, MyApp.Events.FundsDeposited],
            reactors: [MyApp.Reactors.NotificationReactor],
            reducers: [MyApp.Reducers.AccountReducer]}
        ]

        Supervisor.start_link(children, strategy: :one_for_one)
      end
    end

## Defining Event Types

    defmodule MyApp.Events.AccountOpened do
      use Chronicle.EventType, id: "account-opened-v1"
      defstruct [:account_id, :owner_name, :initial_balance]
    end

## Appending Events

    Chronicle.append("account-42", %MyApp.Events.AccountOpened{
      account_id: "account-42",
      owner_name: "Alice",
      initial_balance: 1000
    })

## Reading Read Models

    {:ok, account} = Chronicle.read_model(MyApp.ReadModels.Account, "account-42")

## Defining Reactors

    defmodule MyApp.Reactors.NotificationReactor do
      use Chronicle.Reactor

      @handles MyApp.Events.AccountOpened

      @impl true
      def handle(%MyApp.Events.AccountOpened{} = event, _context) do
        MyApp.Mailer.welcome(event.owner_name)
        :ok
      end
    end

## Defining Reducers

    defmodule MyApp.Reducers.AccountReducer do
      use Chronicle.Reducer, model: MyApp.ReadModels.Account

      @handles MyApp.Events.AccountOpened

      @impl true
      def reduce(%MyApp.Events.AccountOpened{} = event, _model, _context) do
        %MyApp.ReadModels.Account{
          account_id: event.account_id,
          owner_name: event.owner_name,
          balance: event.initial_balance
        }
      end
    end

## Modules

  * `Chronicle.Client` — the main supervisor; start it in your supervision tree
  * `Chronicle.EventType` — macro for defining event types
  * `Chronicle.Reactor` — behaviour for event reactors
  * `Chronicle.Reducer` — behaviour for read model reducers
  * `Chronicle.ReadModel` — macro for read model structs with embedded projection DSL
  * `Chronicle.EventLog` — append and query events
  * `Chronicle.ReadModels` — query read model instances
  * `Chronicle.Connections.ConnectionString` — parse and format connection strings
  * `Chronicle.Connections.Connection` — resilient gRPC channel management

# `all`

```elixir
@spec all(
  module(),
  keyword()
) :: {:ok, [struct()]} | {:error, term()}
```

Returns all instances of the given read model.

Delegates to `Chronicle.ReadModels.all/2`.

# `append`

```elixir
@spec append(String.t(), struct(), keyword()) :: :ok | {:error, term()}
```

Appends a single event to the event log for the given event source.

Delegates to `Chronicle.EventLog.append/3`.

## Options

  * `:client` — the client name (default: `Chronicle.Client`)
  * `:namespace` — overrides the client's default namespace
  * `:tags` — list of tag strings
  * `:subject` — the identity subject string

# `append_many`

```elixir
@spec append_many(String.t(), [struct()], keyword()) :: :ok | {:error, term()}
```

Appends multiple events to the event log for the given event source.

Delegates to `Chronicle.EventLog.append_many/3`.

# `read_model`

```elixir
@spec read_model(module(), String.t(), keyword()) ::
  {:ok, struct() | nil} | {:error, term()}
```

Fetches a read model instance by its key (typically an event source ID).

Delegates to `Chronicle.ReadModels.get/3`.

Returns `{:ok, model_struct}` on success, or `{:ok, nil}` if not found.

---

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