Packages
Event-driven notification system for Ash Framework with multiple transport types
Current section
Files
Jump to
Current section
Files
lib/resource.ex
defmodule AshDispatch.Resource do
@moduledoc """
Ash.Resource extension for defining event dispatching and counter broadcasting.
This extension adds `dispatch` and `counters` sections to Ash resources, allowing
you to define events and counters that are triggered by resource actions.
## Event Dispatching
defmodule MyApp.Orders.ProductOrder do
use Ash.Resource,
extensions: [AshDispatch.Resource]
actions do
create :create_from_cart do
# ... action logic ...
end
end
dispatch do
event :created,
trigger_on: :create_from_cart,
channels: [
[transport: :in_app, audience: :user],
[transport: :email, audience: :user, delay: 300]
],
content: [
subject: "Order created",
notification_title: "Order created"
]
end
counters do
counter :pending_orders do
trigger_on [:create_from_cart, :cancel]
counter_name :pending_orders
audience :user
invalidates ["orders"]
end
end
end
## Complex Events
For events that need custom logic, reference a callback module:
dispatch do
event :created,
trigger_on: :create_from_cart,
module: MyApp.Events.OrderCreated
end
The callback module implements `AshDispatch.Event` behaviour.
## Auto-Injection
The extension automatically injects changes into actions:
- `DispatchEvent` for events specified in `dispatch` section
- `BroadcastCounterUpdate` for counters specified in `counters` section
You don't need to manually add these changes.
## Features
- **Inline definitions** - Simple events/counters defined in the resource
- **Auto-injection** - Changes automatically added to actions
- **Type safety** - Compile-time validation of configurations
- **Optional complexity** - Use callback modules when needed
"""
use Spark.Dsl.Extension,
sections: [
AshDispatch.Resource.Dsl.dispatch_section(),
AshDispatch.Resource.Dsl.counters_section()
],
transformers: [
AshDispatch.Resource.Transformers.ValidateEvents,
AshDispatch.Resource.Transformers.InjectDispatchChanges,
AshDispatch.Resource.Transformers.InjectCounterBroadcasts,
AshDispatch.Resource.Transformers.InjectEntityNotifier
]
@doc """
Codegen callback for `mix ash.codegen` integration.
Called automatically when running `mix ash.codegen`. Delegates to
`mix ash_dispatch.gen` with the same arguments.
"""
def codegen(args) do
Mix.Task.reenable("ash_dispatch.gen")
Mix.Task.run("ash_dispatch.gen", args)
end
end