PubSub integration for cross-process resource invalidation.
When a Lavash form submits successfully, it broadcasts to all subscribers watching that resource. Supports both coarse-grained (resource-level) and fine-grained (combination-based) invalidation.
Configuration
Configure your app's PubSub in config:
config :lavash, pubsub: MyApp.PubSubTopic Types
Resource-level topics
Format: lavash:<Resource>
Example: lavash:MyApp.Product
Used when no specific attributes are being watched.
Combination topics
Format: lavash:<Resource>:<attr1>=<val1>&<attr2>=<val2>
Example: lavash:MyApp.Product:category_id=abc-123&in_stock=true
Used for fine-grained invalidation based on filter combinations.
Attributes are sorted alphabetically for consistent topic names.
How it works
- On mount, Lavash subscribes to a combination topic based on current filter values
- On mutation, broadcasts to all subset combinations of the record's attribute values
- This ensures any consumer filtering on any subset of those attributes gets notified
- Both old and new values are broadcast to handle additions and removals
Example
A product with category_id=cat-a, in_stock=true will broadcast to:
lavash:Product:category_id=cat-a&in_stock=true(both specified)lavash:Product:category_id=cat-a(only category)lavash:Product:in_stock=true(only in_stock)lavash:Product(resource-level, neither specified)
A consumer filtering category_id=cat-a, in_stock=nil subscribes to:
lavash:Product:category_id=cat-a(only category specified)
Summary
Functions
Broadcast a resource mutation to all resource-level subscribers.
Broadcast a mutation to all relevant combination topics.
Returns the combination topic for a specific set of filter values. Only includes attributes with non-nil values. Attributes are sorted alphabetically.
Returns the configured PubSub module, or nil if not configured.
Returns the resource-level topic name.
Subscribe the current process to all invalidation events for a resource.
Subscribe to invalidation events for a specific combination of attribute values.
Unsubscribe from a specific combination topic.
Functions
Broadcast a resource mutation to all resource-level subscribers.
Broadcast a mutation to all relevant combination topics.
Takes attribute changes (old and new values) and broadcasts to all subset combinations. This ensures any consumer filtering on any subset of these attributes will be notified.
Parameters
resource: The Ash resource modulewatched_attrs: List of attributes that consumers might filter onchanges: Map of %{attr => {old_value, new_value}} for changed attributesunchanged: Map of %{attr => value} for unchanged attributes
Example
# Product's category changed from cat-a to cat-b, in_stock stayed true
broadcast_mutation(Product, [:category_id, :in_stock],
%{category_id: {"cat-a", "cat-b"}},
%{in_stock: true}
)
# This broadcasts to topics for both old and new values:
# Old value combinations (for removals from queries):
# - lavash:Product:category_id=cat-a&in_stock=true
# - lavash:Product:category_id=cat-a
# - lavash:Product:in_stock=true
# New value combinations (for additions to queries):
# - lavash:Product:category_id=cat-b&in_stock=true
# - lavash:Product:category_id=cat-b
# - lavash:Product:in_stock=true (same as old, deduped)
Returns the combination topic for a specific set of filter values. Only includes attributes with non-nil values. Attributes are sorted alphabetically.
Returns the configured PubSub module, or nil if not configured.
Returns the resource-level topic name.
Subscribe the current process to all invalidation events for a resource.
Subscribe to invalidation events for a specific combination of attribute values.
The filter_values map contains the current filter state. Attributes with nil values are considered "not filtered" and are excluded from the topic.
Examples
# Filtering by category only
subscribe_combination(Product, [:category_id, :in_stock], %{category_id: "cat-a", in_stock: nil})
# Subscribes to: lavash:Product:category_id=cat-a
# Filtering by both
subscribe_combination(Product, [:category_id, :in_stock], %{category_id: "cat-a", in_stock: true})
# Subscribes to: lavash:Product:category_id=cat-a&in_stock=true
# No filters active
subscribe_combination(Product, [:category_id, :in_stock], %{category_id: nil, in_stock: nil})
# Subscribes to: lavash:Product (resource-level)
Unsubscribe from a specific combination topic.