Skip to content

feat: CSR/SSRv1 context #5356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 16, 2025
Merged

feat: CSR/SSRv1 context #5356

merged 19 commits into from
May 16, 2025

Conversation

jhefferman-sfdc
Copy link
Collaborator

@jhefferman-sfdc jhefferman-sfdc commented May 2, 2025

Details

Expose context api for CSR/SSRv1 for state management support
See: https://github.com/salesforce/lightning-labs/tree/main/packages/%40lwc/state for context on the context :)

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.

GUS work item

W-18293936

@jhefferman-sfdc jhefferman-sfdc requested a review from a team as a code owner May 2, 2025 16:07
@jhefferman-sfdc
Copy link
Collaborator Author

Working on hydration tests, I know that is missing

@wjhsf
Copy link
Collaborator

wjhsf commented May 2, 2025

  • Why are we adding state management to LWC?
  • Is this just a copy/paste of @lwc/state from the lightning-labs repo into here, or is it something else?
  • This was also done in feat: bake context into lwc framework #4995, why didn't we merge that PR? What's different/better about this PR?

@jhefferman-sfdc
Copy link
Collaborator Author

jhefferman-sfdc commented May 3, 2025

  • Why are we adding state management to LWC?

We are not, this provides the API required for state management but doesn't implement it.

  • Is this just a copy/paste of @lwc/state from the lightning-labs repo into here, or is it something else?

It's something else

What's different?

  • This PR is environment agnostic
  • The test strategy in this PR doesn't involve a full state management implementation. It is less brittle and only covers the LWC contract
  • The test coverage in this PR is more extensive
  • Other simplifications (feel free to diff/browse)

@divmain
Copy link
Collaborator

divmain commented May 5, 2025

This is looking great @jhefferman-sfdc! Definitely moving in the right direction.

@jhefferman-sfdc jhefferman-sfdc requested a review from divmain May 10, 2025 02:19
contextVariety: V,
providedContextSignal: Signal<unknown>
): void {
// registerContextProvider is called one time when the component is first provided context.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this always true? For example, what if we instantiate a state manager (which implements ContextConnector) and attach it as a prop to two separate components?

I think we decided that "the latest context wins" in scenarios like that. But let's make sure the comments reflect that potential use-case, and make sure the implementation/tests cover that use case, as well.

Copy link
Collaborator Author

@jhefferman-sfdc jhefferman-sfdc May 14, 2025

Choose a reason for hiding this comment

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

Is this always true? For example, what if we instantiate a state manager (which implements ContextConnector) and attach it as a prop to two separate components?

IIUC, yes? A state manager doesn't instantiate ContextConnector but rather consumes it? This is based on the the experimental impl here.

There is one listener per contextful component (aka a component we know to have associated context).

  • The consumer event is fired and bubbles up, searching for the required context variety
  • This one listener on the provider calls back to the consumer and says "hey, is any of my context what you are looking for?"
  • If it there is a match, bubbling stops and if no match, the search continues

Please correct any misunderstandings I may have.

I think we decided that "the latest context wins" in scenarios like that. But let's make sure the comments reflect that potential use-case, and make sure the implementation/tests cover that use case, as well.

Yes that scenario is encapsulated below, here. I changed it to a warn to align with Signals implementation.

}
}

export function disconnectContext(vm: VM) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The exposed functions look good. Let's just add docs, and I think they're finished.

Copy link
Collaborator Author

@jhefferman-sfdc jhefferman-sfdc May 14, 2025

Choose a reason for hiding this comment

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

These are not exposed via engine-server/dom - IIUC:

  • ContextConnector (previously, ContextRuntimeAdaptor) is the exposed API
  • connectContext (this function) is called once per component lifecycle, privately by vm.ts here.
  • connectContext purpose is to make any component-associated context providable and consumable (via ContextConnector).
  • I documented ContextConnector and the other API here.
  • I also exported it as a public interface here is the public API?
  • This aligns with prior ContextRuntimeAdaptor

@@ -702,6 +703,12 @@ export function runConnectedCallback(vm: VM) {
if (hasWireAdapters(vm)) {
connectWireAdapters(vm);
}

if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@divmain I protected the new context implementation with the same ENABLE_EXPERIMENTAL_SIGNALS for now, in case rollback is required? Could change to separate gate but I figured the features are closely related?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Re-using the flag makes sense to me. They're closely entangled, as you say.

@jhefferman-sfdc jhefferman-sfdc requested a review from divmain May 14, 2025 22:46
Copy link
Collaborator

@divmain divmain left a comment

Choose a reason for hiding this comment

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

Ship it!

@@ -702,6 +703,12 @@ export function runConnectedCallback(vm: VM) {
if (hasWireAdapters(vm)) {
connectWireAdapters(vm);
}

if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Re-using the flag makes sense to me. They're closely entangled, as you say.

@jhefferman-sfdc jhefferman-sfdc merged commit 7454013 into master May 16, 2025
6 checks passed
@jhefferman-sfdc jhefferman-sfdc deleted the u/jhefferman/state/initial branch May 16, 2025 14:42
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.

3 participants