sycamore
sycamore copied to clipboard
Remove data-hk attribute after hydration
Currently, hydrating multiple components on the same page in sycamore does not work. This is because, across mount boundaries, elements can have the same data-hk value and thus confuses sycamore.
This can be fixed by simply removing data-hk immediately after each element is hydrated. We can only do in-order from-top-to-bottom multi-component hydration, but that's more than sufficient.
This PR allows sycamore to support island architecture. rel https://github.com/sycamore-rs/sycamore/issues/200
Codecov Report
Attention: Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
Project coverage is 64.92%. Comparing base (
3057f67) to head (4c91ecb). Report is 64 commits behind head on master.
| Files with missing lines | Patch % | Lines |
|---|---|---|
| packages/sycamore-web/src/hydrate.rs | 0.00% | 4 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## master #537 +/- ##
==========================================
- Coverage 64.96% 64.92% -0.04%
==========================================
Files 53 53
Lines 8515 8517 +2
==========================================
- Hits 5532 5530 -2
- Misses 2983 2987 +4
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Thanks, but I'm not sure if this actually works. If there are conflicting data-hk in the DOM, when we call querySelector("[data-hk=...]), which node we get is undefined (or at least very not obvious).
I think the proper solution here is to simply not generate duplicate hydration keys. A simple solution is to simply add another number to the key. Right now, we are using two numbers: one for the component and another for the element (or templates, once #536 is merged). I could imagine a third number to identify which generation, for the lack of a better term, to distinguish between otherwise conflicting hydration keys.
querySelector has this defined in the spec. It's always depth-first, pre-order, and always returns the first match. See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
I think the proper solution
The best solution is actually to just call Element::querySelector (from the root element of the hydration) instead of Document::querySelector. That will ensure that there's no duplicate and it'll even work for partial hydration (which island arch eventually needs). I just don't know the codebase enough for how/where to actually pass the root element (do we need another hydration context or something?).
The best solution is actually to just call
Element::querySelector(from the root element of the hydration) instead ofDocument::querySelector. That will ensure that there's no duplicate and it'll even work for partial hydration (which island arch eventually needs). I just don't know the codebase enough for how/where to actually pass the root element (do we need another hydration context or something?).
Ah that might actually make more sense than what I was proposing. Since all the logic for querying the next hydratable element is contained inside get_next_element, this change should not be very intrusive.
The root node would then need to tracked inside HydrationRegistry which would be added when the HydrationRegistry is created inside hydrate and hydrate_to.
Also please let me know if you would still like to work on this.
I'll give it a try. Will let you know if I'm stuck!
I'll give it a try. Will let you know if I'm stuck!
Are you still working on this? If you're not, please let me know and I can take over. As always, don't hesitate to ask me with any questions you have.
Superseded by #679