Chronicle.Seeding (cratis_chronicle v1.0.2)

Copy Markdown View Source

Accumulates and registers seed events with Chronicle.

This module provides a builder API for accumulating events during seeder discovery, then organizing and sending them to the Chronicle server.

Usage

Typically used within a Chronicle.Seeding.Seeder.seed/1 callback:

def seed(builder) do
  builder
  |> Chronicle.Seeding.for(MyEvent, "aggregate-1", [%MyEvent{...}])
  |> Chronicle.Seeding.for_event_source("aggregate-2", [%Event1{...}, %Event2{...}])
end

Lifecycle

  1. Discoverydiscover/2 finds all seeder modules
  2. Accumulation — Each seeder's seed/1 is called, populating the builder
  3. Registrationregister/1 organizes entries and sends them to Chronicle

Events are organized by:

  • Global vs. namespaced
  • Event type and event source (dual organization for server efficiency)

Summary

Functions

Discovers seeder modules and invokes them to populate the builder.

Seeds events of a specific type for an event source.

Seeds multiple event types for a single event source.

Scopes subsequent events to a specific namespace.

Registers all accumulated seed events with Chronicle.

Types

append_many_fun()

@type append_many_fun() :: (event_source_id(), [struct()], keyword() ->
                        :ok | {:error, term()})

event_source_id()

@type event_source_id() :: String.t()

has_events_for_fun()

@type has_events_for_fun() :: (event_source_id(), keyword() ->
                           {:ok, boolean()} | {:error, term()})

namespace()

@type namespace() :: String.t()

seeding_entry()

@type seeding_entry() :: %{
  event_source_id: event_source_id(),
  event_type_id: String.t(),
  event: struct(),
  tags: [String.t()],
  is_global: boolean(),
  target_namespace: namespace() | nil
}

t()

@type t() :: %Chronicle.Seeding{
  append_many: append_many_fun() | nil,
  client: atom() | nil,
  connection: atom(),
  entries: [seeding_entry()],
  event_store: String.t(),
  event_types: module(),
  has_events_for: has_events_for_fun() | nil,
  namespace: String.t()
}

Functions

discover(builder, seeder_modules)

@spec discover(t(), [module()]) :: t()

Discovers seeder modules and invokes them to populate the builder.

Iterates through all provided seeder modules, instantiates each, calls seed/1, and accumulates their events.

Returns the populated builder struct.

for(builder, event_type, event_source_id, events)

@spec for(t(), module(), event_source_id(), [struct()]) :: t()

Seeds events of a specific type for an event source.

Parameters

  • builder — the seeding builder
  • event_type — the event type module (must use Chronicle.Events.EventType)
  • event_source_id — the event source (aggregate) ID
  • events — list of event structs

Example

builder
|> Chronicle.Seeding.for(MyApp.Events.AccountOpened, "account-1", [
  %MyApp.Events.AccountOpened{account_id: "account-1", owner_name: "Alice"}
])

for_event_source(builder, event_source_id, events)

@spec for_event_source(t(), event_source_id(), [struct()]) :: t()

Seeds multiple event types for a single event source.

Parameters

  • builder — the seeding builder
  • event_source_id — the event source (aggregate) ID
  • events — list of event structs (can be different types)

Example

builder
|> Chronicle.Seeding.for_event_source("account-1", [
  %MyApp.Events.AccountOpened{account_id: "account-1", owner_name: "Alice"},
  %MyApp.Events.FundsDeposited{account_id: "account-1", amount: 500}
])

for_namespace(builder, namespace, fun)

@spec for_namespace(t(), namespace(), (t() -> t())) :: t()

Scopes subsequent events to a specific namespace.

Returns a scoped builder that targets the given namespace.

Parameters

  • builder — the seeding builder
  • namespace — the target namespace
  • fun — a function receiving a scoped builder

Example

builder
|> Chronicle.Seeding.for_namespace("production", fn scoped ->
  scoped
  |> Chronicle.Seeding.for(MyEvent, "aggregate-1", [%MyEvent{...}])
end)

register(builder)

@spec register(t()) :: :ok | {:error, term()}

Registers all accumulated seed events with Chronicle.

Organizes entries by global/namespaced, then by event type and event source, and sends them to the Chronicle server via gRPC.

This is typically called automatically by Chronicle.Client during startup.