Lavash.PubSub (Lavash v0.3.0-rc.3)

Copy Markdown View Source

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.PubSub

Topic 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

  1. On mount, Lavash subscribes to a combination topic based on current filter values
  2. On mutation, broadcasts to all subset combinations of the record's attribute values
  3. This ensures any consumer filtering on any subset of those attributes gets notified
  4. 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.

topic(resource) deprecated

Unsubscribe from a specific combination topic.

Functions

broadcast(resource)

Broadcast a resource mutation to all resource-level subscribers.

broadcast_mutation(resource, watched_attrs, changes, unchanged \\ %{})

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 module
  • watched_attrs: List of attributes that consumers might filter on
  • changes: Map of %{attr => {old_value, new_value}} for changed attributes
  • unchanged: 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)

combination_topic(resource, watched_attrs, filter_values)

Returns the combination topic for a specific set of filter values. Only includes attributes with non-nil values. Attributes are sorted alphabetically.

pubsub()

Returns the configured PubSub module, or nil if not configured.

resource_topic(resource)

Returns the resource-level topic name.

subscribe(resource)

Subscribe the current process to all invalidation events for a resource.

subscribe_combination(resource, watched_attrs, filter_values)

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)

topic(resource)

This function is deprecated. Use resource_topic/1 instead.

unsubscribe_combination(resource, watched_attrs, filter_values)

Unsubscribe from a specific combination topic.