Packages
phoenix_kit
1.7.30
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/shop/events.ex
defmodule PhoenixKit.Modules.Shop.Events do
@moduledoc """
PubSub event broadcasting for Shop cart synchronization.
This module provides functions to broadcast cart changes across
multiple browser tabs and devices for the same user/session.
## Topics
- `shop:cart:user:{user_id}` - Cart events for authenticated users
- `shop:cart:session:{session_id}` - Cart events for guest sessions
## Events
### Cart Events
- `{:cart_updated, cart}` - Cart totals changed (generic update)
- `{:item_added, cart, item}` - Item added to cart
- `{:item_removed, cart, item_id}` - Item removed from cart
- `{:quantity_updated, cart, item}` - Item quantity changed
- `{:shipping_selected, cart}` - Shipping method selected/changed
- `{:payment_selected, cart}` - Payment option selected/changed
- `{:cart_cleared, cart}` - All items removed from cart
## Examples
# Subscribe to cart updates for authenticated user
Events.subscribe_to_user_cart(user_id)
# Subscribe to cart updates for guest session
Events.subscribe_to_session_cart(session_id)
# Broadcast item added
Events.broadcast_item_added(cart, item)
# Handle in LiveView
def handle_info({:item_added, cart, _item}, socket) do
{:noreply, assign(socket, :cart, cart)}
end
"""
alias PhoenixKit.Modules.Shop.Cart
alias PhoenixKit.PubSub.Manager
# ============================================
# TOPIC BUILDERS
# ============================================
@doc """
Returns the PubSub topic for a user's cart.
"""
def user_cart_topic(user_id) when not is_nil(user_id) do
"shop:cart:user:#{user_id}"
end
@doc """
Returns the PubSub topic for a session's cart.
"""
def session_cart_topic(session_id) when not is_nil(session_id) do
"shop:cart:session:#{session_id}"
end
@doc """
Returns the appropriate topic(s) for a cart.
"""
def cart_topics(%Cart{user_id: user_id, session_id: session_id}) do
topics = []
topics = if user_id, do: [user_cart_topic(user_id) | topics], else: topics
topics = if session_id, do: [session_cart_topic(session_id) | topics], else: topics
topics
end
# ============================================
# SUBSCRIPTION FUNCTIONS
# ============================================
@doc """
Subscribes to cart events for a specific cart.
Subscribes to all relevant topics (user and/or session).
"""
def subscribe_to_cart(%Cart{} = cart) do
cart
|> cart_topics()
|> Enum.each(&Manager.subscribe/1)
end
@doc """
Subscribes to cart events for an authenticated user.
"""
def subscribe_to_user_cart(user_id) when not is_nil(user_id) do
Manager.subscribe(user_cart_topic(user_id))
end
@doc """
Subscribes to cart events for a guest session.
"""
def subscribe_to_session_cart(session_id) when not is_nil(session_id) do
Manager.subscribe(session_cart_topic(session_id))
end
@doc """
Unsubscribes from cart events for a specific cart.
"""
def unsubscribe_from_cart(%Cart{} = cart) do
cart
|> cart_topics()
|> Enum.each(&Manager.unsubscribe/1)
end
@doc """
Unsubscribes from cart events for an authenticated user.
"""
def unsubscribe_from_user_cart(user_id) when not is_nil(user_id) do
Manager.unsubscribe(user_cart_topic(user_id))
end
@doc """
Unsubscribes from cart events for a guest session.
"""
def unsubscribe_from_session_cart(session_id) when not is_nil(session_id) do
Manager.unsubscribe(session_cart_topic(session_id))
end
# ============================================
# BROADCAST FUNCTIONS
# ============================================
@doc """
Broadcasts a generic cart update event.
"""
def broadcast_cart_updated(%Cart{} = cart) do
broadcast_to_cart(cart, {:cart_updated, cart})
end
@doc """
Broadcasts item added event.
"""
def broadcast_item_added(%Cart{} = cart, item) do
broadcast_to_cart(cart, {:item_added, cart, item})
end
@doc """
Broadcasts item removed event.
"""
def broadcast_item_removed(%Cart{} = cart, item_id) do
broadcast_to_cart(cart, {:item_removed, cart, item_id})
end
@doc """
Broadcasts quantity updated event.
"""
def broadcast_quantity_updated(%Cart{} = cart, item) do
broadcast_to_cart(cart, {:quantity_updated, cart, item})
end
@doc """
Broadcasts shipping method selected event.
"""
def broadcast_shipping_selected(%Cart{} = cart) do
broadcast_to_cart(cart, {:shipping_selected, cart})
end
@doc """
Broadcasts payment option selected event.
"""
def broadcast_payment_selected(%Cart{} = cart) do
broadcast_to_cart(cart, {:payment_selected, cart})
end
@doc """
Broadcasts cart cleared event.
"""
def broadcast_cart_cleared(%Cart{} = cart) do
broadcast_to_cart(cart, {:cart_cleared, cart})
end
# ============================================
# PRIVATE FUNCTIONS
# ============================================
defp broadcast_to_cart(%Cart{} = cart, message) do
cart
|> cart_topics()
|> Enum.each(fn topic ->
Manager.broadcast(topic, message)
end)
end
end