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

Supervisor that manages a Chronicle connection and all registered observers.

`Chronicle.Client` is the main entry point for the Chronicle Elixir client.
Start it in your application's supervision tree, providing a connection
string and the list of event types, migrations, reactors, reducers, read
models, discoverable webhooks, and discoverable event store subscriptions to
register.

## Usage

In your `Application.start/2`:

    def start(_type, _args) do
      children = [
        {Chronicle.Client,
          connection_string: "chronicle://localhost:35000",
          event_store: "my-store",
          event_types: [
            MyApp.Events.AccountOpened,
            MyApp.Events.FundsDeposited
          ],
          migrations: [MyApp.Migrations.AccountOpenedV2Migration],
          reactors: [MyApp.Reactors.NotificationReactor],
          reducers: [MyApp.Reducers.AccountReducer],
          read_models: [MyApp.ReadModels.Account],
          webhooks: [MyApp.WebHooks.AccountEvents],
          event_store_subscriptions: [
            MyApp.EventStoreSubscriptions.DefaultAccountEvents
          ]}
      ]

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

Or enable artifact auto-discovery from an OTP application:

    {Chronicle.Client,
      connection_string: "chronicle://localhost:35000",
      event_store: "my-store",
      otp_app: :my_app}

In that mode, Chronicle scans modules in `:my_app` and discovers artifacts
generated by Chronicle macros (`use Chronicle.Events.EventType`,
`use Chronicle.Events.Migration`, `use Chronicle.Seeding.Seeder`,
`use Chronicle.Reactors.Reactor`, `use Chronicle.Reducers.Reducer`, `use Chronicle.ReadModels.ReadModel`,
`use Chronicle.WebHooks.Webhook`, and
`use Chronicle.EventStoreSubscriptions.Subscription`).

By default, Chronicle also auto-discovers artifacts from loaded modules,
so consumers can start with minimal configuration.

Read models that contain `from/2`, `join/2`, or `removed_with/2` declarations
are automatically registered as server-side projections.

## Multiple clients

You can start multiple clients with different names:

    {Chronicle.Client,
      name: :bank_chronicle,
      connection_string: "chronicle://bank-server:35000",
      event_store: "bank"}

    {Chronicle.Client,
      name: :crm_chronicle,
      connection_string: "chronicle://crm-server:35000",
      event_store: "crm"}

## Options

  * `:name` — registered name for this client. Defaults to `Chronicle.Client`.
  * `:connection_string` — a connection string binary or
    `Chronicle.Connections.ConnectionString` struct. Defaults to
    `ConnectionString.default/0` (localhost:35000).
  * `:event_store` — the event store name. Defaults to `"default"`.
  * `:namespace` — the namespace within the event store. Defaults to `"default"`.
  * `:discover` — enable/disable artifact auto-discovery. Defaults to `true`.
  * `:otp_app` — optional OTP application to auto-discover Chronicle artifacts from.
    When omitted, discovery scans loaded modules. Discovered artifacts are
    merged with explicit `:event_types`, `:migrations`, `:reactors`,
    `:reducers`, `:read_models`, `:webhooks`, and
    `:event_store_subscriptions` entries.
  * `:event_types` — list of event type modules to register with the event store.
  * `:event_sources` — list of `Chronicle.EventSources.EventSource` modules to register
    with the event store (also discovered automatically).
  * `:migrations` — list of migration modules to register with the event store.
  * `:reactors` — list of reactor modules to start (each `use Chronicle.Reactors.Reactor`).
  * `:reducers` — list of reducer modules to start (each `use Chronicle.Reducers.Reducer`).
  * `:read_models` — list of read model modules (each `use Chronicle.ReadModels.ReadModel`).
    Modules that contain `from/2` declarations are registered as model-bound projections.
  * `:projections` — list of declarative projection modules (each
    `use Chronicle.Projections.Projection`). These are standalone projection definitions
    that reference a separate read model module.
  * `:constraints` — list of standalone constraint modules (each
    `use Chronicle.Events.Constraint`). These are merged with model-bound constraints
    declared on registered event types.
  * `:global_handlers` — list of shared handler modules (each
    `use Chronicle.Projections.GlobalHandler`). Their mappings are merged into every read
    model or declarative projection whose `variant_of/2` names the same identity; never
    registered as a projection on their own.
  * `:seeders` — list of seeder modules (each `use Chronicle.Seeding.Seeder`). Seeders
    populate the event store with initial events during client startup.
  * `:webhooks` — list of discoverable webhook modules (each
    `use Chronicle.WebHooks.Webhook`). These are registered on startup.
  * `:captures` — list of discoverable capture modules (each `use Chronicle.Captures.Capture`).
    These are registered on startup (see `Chronicle.Captures.register_discovered/1`).
  * `:event_store_subscriptions` — list of discoverable event store
    subscription modules (each
    `use Chronicle.EventStoreSubscriptions.Subscription`). These are
    registered on startup.
  * `:default_sink_type_id` — the default sink type used when registering
    projections and reducers. Accepts an atom (`:mongodb`, `:sql`,
    `:in_memory`, `:none`) or a raw sink type string. Defaults to
    `:mongodb`. See `Chronicle.Sinks.WellKnownSinkTypes`.
  * `:drift_policy` — `:ignore`, `:warn` (default) or `:fail`. Controls what happens when
    the artifacts about to be registered look like they've drifted from what the kernel
    already has — an event type generation whose schema changed without a bumped
    `:generation`, a registered reactor/reducer/projection missing from the current code,
    or one whose handled event types changed. `:ignore` skips the check and its kernel
    calls. `:warn` logs any findings and registers anyway. `:fail` logs findings and
    refuses to register when a `:warning`-severity finding exists (an event type or
    reactor finding); a reducer or projection finding is `:info` and never blocks. If the
    check itself cannot complete, `:warn` logs and continues and `:fail` stops — an
    indeterminate result is never treated as clean. See `Chronicle.Discovery.DriftDetector`
    and `Chronicle.Client.identity_drift/1`.
  * `:strict_validation` — defaults to `false`. When two modules represent the same generation
    of an event type, or more than one migrator bridges the same pair of generations, the
    client logs the full error at startup and continues. Set to `true` to raise at startup
    instead, before anything connects. See `Chronicle.Events.EventTypes.validate/2`.
  * `:warn_defaulted_ids` — defaults to `true`. A reactor, reducer or declarative
    projection with no explicit `:id` defaults it to the module name — renaming or moving
    the module then silently resets its observation position. Discovery logs a one-time
    warning (per module, for the life of the BEAM node) naming the module and how to pin
    its id; set to `false` to suppress it. See `Chronicle.Discovery.DefaultedIdWarning`.
  * `:event_generation_delivery` — the default generation delivery
    (`:compatibility` or `:pinned`) for every reactor and reducer that
    doesn't set its own `:generation_delivery`. Defaults to `:compatibility`.
    See "Pinned generation delivery" on `Chronicle.Reactors.Reactor` and
    `Chronicle.Reducers.Reducer`.
  * `:skip_tls_validation` — overrides the connection string's
    `skipTlsValidation` query option. See `Chronicle.Connections.Connection`.
  * `:load_balancer` — overrides the connection string's `loadBalancer`
    query option (`:least_connections`, `:round_robin`, or `:random`), used
    to pick among multiple hosts or DNS SRV-resolved addresses. See
    `Chronicle.Connections.LoadBalancer`.
  * `:max_concurrent_partitions` — how many partitions (event sources for a reactor,
    read model instances for a reducer) each reactor and reducer handles at the same time.
    Defaults to `16`. Batches for one partition always run one at a time and in order. Set
    to `1` to handle every batch one after another, as versions before 3.16 did.
  * `:keepalive_timeout` — milliseconds without a keepalive from the kernel after
    which the session is treated as dead and reconnected. Defaults to `5_000`, matching
    the kernel's `connectedClients.staleThresholdSeconds` (5); raise both together.
  * `:dedicated_session_channel` — defaults to `true`. The session (the Connect
    stream and its keepalive answers) runs on its own HTTP/2 connection to the same
    server, so large reactor and reducer results cannot hold its keepalives back. Set
    to `false` to share one connection for everything.
  * `:concurrency` — the default concurrency scope strategy applied to an append that has
    no explicit `:concurrency_scope` and none derived from an event source definition's
    declared dimensions. `default: :none` (the default) sends no constraint, matching prior
    behavior. `default: :optimistic` reads the tail narrowed the same way the append is
    routed and expects nothing to have been appended since, mirroring the .NET client's
    `OptimisticConcurrencyStrategy`. `check_first_append: false` (default) leaves a first
    append into an empty narrowing unchecked; `true` expects no event matching it yet (see
    `Chronicle.Events.ConcurrencyScope.expecting_no_matching_event/1`).

## Convenience functions

Once started, use `Chronicle.append/3` and `Chronicle.read_model/3` for the
most common operations, or use the subsystem modules directly:

  * `Chronicle.EventSequences.EventLog` — append and query events
  * `Chronicle.ReadModels` — query read model instances
  * `Chronicle.Projections` — ad-hoc query a PDL declaration and wait for a projection
  * `Chronicle.Events.EventTypes` — manage event type registrations
  * `Chronicle.Jobs` — inspect and control Chronicle jobs
  * `Chronicle.WebHooks` — inspect and register webhooks
  * `Chronicle.EventStoreSubscriptions` — register cross-store subscriptions

# `await_registration`

```elixir
@spec await_registration(atom(), timeout()) :: :ok | {:error, term()}
```

Waits until registration has completed, so appends and reads that depend on the registered
artifacts can start.

Returns `:ok` once registered, `{:error, {:failed, status}}` if the kernel rejected a
registration for good (the status carries the kernel's message), or `{:error, :timeout}`.
`timeout` is in milliseconds (default `30_000`).

    {:ok, _} = Chronicle.Client.start_link(...)
    :ok = Chronicle.Client.await_registration()

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `config`

```elixir
@spec config(atom() | pid()) :: map()
```

Returns the stored configuration for the given client name.

Used internally by `Chronicle.EventSequences.EventLog`, `Chronicle.ReadModels`, etc.

# `discovery_report`

```elixir
@spec discovery_report(atom()) :: Chronicle.Discovery.Report.t()
```

Returns the artifact discovery report built when this client started.

See `Chronicle.Discovery.Report`. Logged at `:info` (summary) and `:debug` (full report)
during `init/1`; this is how to get at it afterwards.

# `identity_drift`

```elixir
@spec identity_drift(atom()) :: [Chronicle.Discovery.Drift.t()]
```

Returns the most recent artifact identity drift findings computed before registration.

Empty before the first registration attempt, when `drift_policy: :ignore`, or when none
were found. See `Chronicle.Discovery.Drift` and the `:drift_policy` client option.

# `registration_status`

```elixir
@spec registration_status(atom()) :: map()
```

The registration status of a client: whether its event types, constraints, read models,
projections and the rest have been registered with the kernel.

Returns `%{state: :pending | :registering | :registered | :failed, attempts: n, error: term | nil,
next_retry_in: ms | nil}`. Registration is retried with backoff (see
`Chronicle.Registration.RetryPolicy`), so `:registering` with a non-nil `:error` means the kernel
could not be reached or rejected an attempt, and `:failed` means it was rejected for good.

# `start_link`

```elixir
@spec start_link(keyword()) :: Supervisor.on_start()
```

Starts a Chronicle client supervisor linked to the current process.

---

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