Skuld.Effects.EventAccumulator (skuld v0.1.26)
View SourceEffect for accumulating events during computation.
Accumulates events in a simple list, preserving emission order. This follows the Decider pattern where Events are facts about what happened.
Example
alias Skuld.Effects.{EventAccumulator, ChangeEvent}
alias Skuld.Comp
use Skuld.Syntax
# Accumulate events during computation
comp do
user_cs = User.changeset(%User{}, %{name: "Alice"})
_ <- EventAccumulator.emit(ChangeEvent.insert(user_cs))
order_cs = Order.changeset(%Order{}, %{user_id: 1})
_ <- EventAccumulator.emit(ChangeEvent.insert(order_cs))
return(:ok)
end
|> EventAccumulator.with_handler(output: &{&1, &2})
|> Comp.run!()
#=> {:ok, [%ChangeEvent{...}, %ChangeEvent{...}]}Options
The with_handler/2 accepts:
:output- Transform function(result, events) -> output. Default returns just the result, discarding the events. Useoutput: &{&1, &2}to get{result, events}.
Grouping Events
If you need to group events by type, use EventAccumulator.IEvent.tag/1:
{result, events} = ...
events_by_tag = Enum.group_by(events, &EventAccumulator.IEvent.tag/1)See Also
Skuld.Effects.Writer- The underlying effectSkuld.Effects.ChangeEvent- Generic changeset operation wrapper
Summary
Functions
Install EventAccumulator handler via catch clause syntax.
Emit an event.
Install handler to capture events.
Functions
Install EventAccumulator handler via catch clause syntax.
Config is opts (or nil for defaults):
catch
EventAccumulator -> nil
EventAccumulator -> [output: fn r, events -> {r, events} end]
@spec emit(term()) :: Skuld.Comp.Types.computation()
Emit an event.
The event will be accumulated in emission order.
Returns :ok.
Example
_ <- EventAccumulator.emit(ChangeEvent.insert(changeset))
_ <- EventAccumulator.emit(%MyCustomEvent{data: "hello"})
@spec with_handler( Skuld.Comp.Types.computation(), keyword() ) :: Skuld.Comp.Types.computation()
Install handler to capture events.
Options
:output- Transform function(result, events) -> output. Default returns just the result, discarding the events. Useoutput: &{&1, &2}to get{result, events}.
Example
comp
|> EventAccumulator.with_handler()
|> Comp.run!()
#=> result (events discarded)
comp
|> EventAccumulator.with_handler(output: &{&1, &2})
|> Comp.run!()
#=> {result, [event1, event2, ...]}
comp
|> EventAccumulator.with_handler(output: fn _result, events -> events end)
|> Comp.run!()
#=> [event1, event2, ...]