59 lines
2.1 KiB
Elixir
59 lines
2.1 KiB
Elixir
defmodule BDS.Events do
|
|
@moduledoc """
|
|
Domain event bus (issue #26, phase 2).
|
|
|
|
Contexts broadcast entity mutations on the same `"entity:changed"` topic
|
|
(and payload shape) that `BDS.CliSync.Watcher` already uses for external
|
|
CLI writes, so every connected client — LiveView shells and TUI sessions
|
|
alike — stays synchronized through one subscription regardless of where
|
|
a change originated.
|
|
"""
|
|
|
|
@entity_topic "entity:changed"
|
|
@settings_topic "settings:changed"
|
|
|
|
@type action :: :created | :updated | :deleted
|
|
|
|
@doc "Subscribe the calling process to entity and settings changes."
|
|
@spec subscribe() :: :ok
|
|
def subscribe do
|
|
:ok = Phoenix.PubSub.subscribe(BDS.PubSub, @entity_topic)
|
|
:ok = Phoenix.PubSub.subscribe(BDS.PubSub, @settings_topic)
|
|
end
|
|
|
|
@doc """
|
|
Broadcast an entity mutation as `{:entity_changed, %{entity: entity,
|
|
entity_id: id, action: action}}` — the same message the CLI sync watcher
|
|
emits, so subscribers handle both through one code path.
|
|
"""
|
|
@spec entity_changed(String.t(), String.t(), action()) :: :ok
|
|
def entity_changed(entity, entity_id, action)
|
|
when is_binary(entity) and is_binary(entity_id) and
|
|
action in [:created, :updated, :deleted] do
|
|
Phoenix.PubSub.broadcast(
|
|
BDS.PubSub,
|
|
@entity_topic,
|
|
{:entity_changed, %{entity: entity, entity_id: entity_id, action: action}}
|
|
)
|
|
end
|
|
|
|
@doc """
|
|
Pipe-friendly broadcast: on `{:ok, %{id: id}}` broadcasts `action` for
|
|
`entity` and returns the result unchanged; any other result passes
|
|
through untouched.
|
|
"""
|
|
@spec broadcast_result(term(), String.t(), action()) :: term()
|
|
def broadcast_result({:ok, %{id: id}} = result, entity, action) when is_binary(id) do
|
|
:ok = entity_changed(entity, id, action)
|
|
result
|
|
end
|
|
|
|
def broadcast_result(result, _entity, _action), do: result
|
|
|
|
@doc "Broadcast a global setting change as `{:settings_changed, key}`."
|
|
@spec settings_changed(String.t()) :: :ok
|
|
def settings_changed(key) when is_binary(key) do
|
|
Phoenix.PubSub.broadcast(BDS.PubSub, @settings_topic, {:settings_changed, key})
|
|
end
|
|
end
|