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{...}])
endLifecycle
- Discovery —
discover/2finds all seeder modules - Accumulation — Each seeder's
seed/1is called, populating the builder - Registration —
register/1organizes 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
Builds the kernel's SeedEventsRequest from the accumulated entries: global entries grouped by
event type and by event source, namespaced entries grouped per namespace.
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
@type append_many_fun() :: (event_source_id(), [struct()], keyword() -> :ok | {:error, term()})
@type event_source_id() :: String.t()
@type has_events_for_fun() :: (event_source_id(), keyword() -> {:ok, boolean()} | {:error, term()})
@type namespace() :: String.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(), seed_events: (map() -> :ok | {:error, term()}) | nil }
Functions
Builds the kernel's SeedEventsRequest from the accumulated entries: global entries grouped by
event type and by event source, namespaced entries grouped per namespace.
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.
@spec for(t(), module(), event_source_id(), [struct()]) :: t()
Seeds events of a specific type for an event source.
Parameters
builder— the seeding builderevent_type— the event type module (mustuse Chronicle.Events.EventType)event_source_id— the event source (aggregate) IDevents— list of event structs
Example
builder
|> Chronicle.Seeding.for(MyApp.Events.AccountOpened, "account-1", [
%MyApp.Events.AccountOpened{account_id: "account-1", owner_name: "Alice"}
])
@spec for_event_source(t(), event_source_id(), [struct()]) :: t()
Seeds multiple event types for a single event source.
Parameters
builder— the seeding builderevent_source_id— the event source (aggregate) IDevents— 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}
])
Scopes subsequent events to a specific namespace.
Returns a scoped builder that targets the given namespace.
Parameters
builder— the seeding buildernamespace— the target namespacefun— a function receiving a scoped builder
Example
builder
|> Chronicle.Seeding.for_namespace("production", fn scoped ->
scoped
|> Chronicle.Seeding.for(MyEvent, "aggregate-1", [%MyEvent{...}])
end)
Registers all accumulated seed events with Chronicle.
Organizes entries by global/namespaced, then by event type and event source, and hands them to the kernel's seeding service, which owns the rest: it tracks what it has already applied (by event source, event type, content and tags), so a new entry added to an event source that was seeded before is applied, an entry that was applied is not applied again, and global entries reach every namespace the kernel knows - exactly as with the .NET client. Re-running on every start is therefore safe.
A seeder whose seed/1 raises is logged as an error and contributes none of its entries
(a seeder is applied whole or not at all); the other seeders still run. Tags declared on the
event type (tags:) are sent with each entry.
This is typically called automatically by Chronicle.Client during startup.