Skip to content
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

feat: bake context into lwc framework #4995

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

feat: bake context into lwc framework #4995

wants to merge 11 commits into from

Conversation

rax-it
Copy link
Contributor

@rax-it rax-it commented Dec 3, 2024

Details

Moving ContextfulLightningElement shim to LWC engine core

Does this pull request introduce a breaking change?

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

Does this pull request introduce an observable change?

  • 🔬 Yes, it does include an observable change.

GUS work item

W-14777911

@rax-it rax-it changed the title chore: bake context into lwc framework [WIP] chore: bake context into lwc framework Dec 3, 2024
@rax-it rax-it changed the title [WIP] chore: bake context into lwc framework chore: bake context into lwc framework Dec 5, 2024
@rax-it rax-it changed the title chore: bake context into lwc framework feat: bake context into lwc framework Dec 5, 2024
@rax-it rax-it marked this pull request as ready for review December 5, 2024 19:02
@rax-it rax-it requested a review from a team as a code owner December 5, 2024 19:02
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like a lot of code just for a Karma test. What is the downside of importing @lwc/state directly? It's already OSS.

await new Promise((resolve) => requestAnimationFrame(resolve));
expect(state.subscribers.size).toBe(0);
});
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

Personally I'd prefer to put all the context-related tests together in one folder, but it's not a big deal.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we're going to inline @lwc/state twice, I think we should at least hoist this up to the Karma level so that we can just import it from both. We could do the same thing we're doing with test-utis to make it importable.

detail: { ...detail, key: getContextKeys().contextEventKey },
});
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Have you looked at the Web Components Community Group proposal for a "context" event? This is an attempt to standardize the concept of passing context between ancestor/descendant components across web component frameworks.

The advantage of using this protocol is that, hypothetically, a non-LWC framework like Lit could use the same protocol and be interoperable with LWC in the same DOM tree.

let isProvidingContext = false;
const providedContextVarieties = new Map<unknown, Signal<unknown>>();
const contextRuntimeAdapter = {
isServerSide: false,
Copy link
Collaborator

Choose a reason for hiding this comment

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

engine-core may execute in a server context, in which case process.env.IS_BROWSER will be false. Does that help here?


component.dispatchEvent(event);
},
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

This may perform better in JS engines if it's an explicit class that we are newing.

if (!isProvidingContext) {
isProvidingContext = true;

component.addEventListener(ContextEventName, (event: any) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We typically use the renderer API for this. Although it's unclear to me how this would work in an SSR context since we don't implement an event listener shim. For the ContextProvider API we implemented a full SSR-compatible shim to make it work (#3165); presumably we ought to do the same here if this needs to run server-side.

logError(
'Multiple contexts of the same variety were provided. Only the first context will be used.'
);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This code is not covered in the Karma tests. You can download the coverage report and see that actually quite a bit is uncovered.

Screenshot 2024-12-10 at 9 59 01 AM

Copy link
Collaborator

@nolanlawson nolanlawson left a comment

Choose a reason for hiding this comment

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

I feel that this code has a large amount of overlap with the existing ContextProvider implementation. Besides (probably?) needing an SSR implementation, it seems to me that it may make sense to implement the two on a shared protocol rather than having two completely distinct side-by-side implementations (unless we truly believe we can deprecate ContextProvider.) 🙂

@rax-it
Copy link
Contributor Author

rax-it commented Dec 17, 2024

@nolanlawson I would love to see @divmain opinion on some of the stuff you mentioned as he has been a driving force behind this, so putting this on hold until then.

@nolanlawson
Copy link
Collaborator

@rax-it I've scheduled a DevSync in January. Let's all 3 of us go over the design then!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants