Skip to content

Allow Lustre applications to subscribe to context changes.#472

Merged
hayleigh-dot-dev merged 7 commits into
mainfrom
hayleigh/app-context-subscribe
May 5, 2026
Merged

Allow Lustre applications to subscribe to context changes.#472
hayleigh-dot-dev merged 7 commits into
mainfrom
hayleigh/app-context-subscribe

Conversation

@hayleigh-dot-dev
Copy link
Copy Markdown
Collaborator

A few versions back we implemented the WCCG Context Protocol by adding the effect.provide effect and a component.on_context_change component option. This allowed any Lustre application to provide context values under a specific key, and for any Lustre component (server or client) to subscribe to changes to those values and dispatch messages.

Because this is a web component protocol we overlooked the fact that applications might want to subscribe to context values too! The most-compelling scenario for this is when a client SPA is rendered in a server component <slot>, enabling a "store pattern" that let's the app subscribe to backend data without the need for an explicit API.

This PR deprecates component.on_context_change entirely in favour of two new effects:

  • effect.subscribe
  • effect.unsubscribe

As context unsubscription is new behaviour, we needed to decide what should happen to existing component context subscriptions are unsubscribed from and then the component is subsequently unmounted and remounted to the DOM. We decided that removed subscriptions should not be re-added when the component reconnects.

Copy link
Copy Markdown
Contributor

@yoshi-monster yoshi-monster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello! Sorry this took a while.

I think it's worth documenting that you need to subscribe/unsubscribe using the connect and disconnect events in components, which means you can't properly subscribe to context changes when using the application constructor combined with register (or server components).

otherwise this looks great thank you!!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a Map I think?

Comment thread src/lustre/effect.gleam Outdated
///
/// Once a value for the given key has been provided, children can [`subscribe`](#subscribe)
/// to changes and receive updates any subsequent times `provide` is called with
/// the same key. This facilities parent-child communication even in cases where
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// the same key. This facilities parent-child communication even in cases where
/// the same key. This facilitates parent-child communication even in cases where

Comment thread src/lustre/effect.gleam Outdated
/// DOM. This effect will decode the context value from the first parent element
/// that has _already provided_ a context for this key at least once. Once a
/// subscription is set up, any changes to the context value will trigger additional
/// messages to be dispatch with the new decoded value.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// messages to be dispatch with the new decoded value.
/// messages to be dispatched with the new decoded value.

Comment thread src/lustre/effect.gleam Outdated
Effect(..empty, synchronous: constants.singleton_list(task))
}

/// Unsubscribe to a context [`subscription`](#subscribe) that was previously set
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Unsubscribe to a context [`subscription`](#subscribe) that was previously set
/// Unsubscribe from a context [`subscription`](#subscribe) that was previously set

@hayleigh-dot-dev hayleigh-dot-dev merged commit 8072b7c into main May 5, 2026
1 check passed
@hayleigh-dot-dev hayleigh-dot-dev deleted the hayleigh/app-context-subscribe branch May 5, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants