Do not observe visible hydrate components more than once (#1015)
* add support for truely unique astro root uids * update test to test uniqueness
This commit is contained in:
parent
16790aee7b
commit
1350d57997
5 changed files with 20 additions and 10 deletions
|
@ -64,5 +64,5 @@ const {editHref} = Astro.props;
|
|||
</li>
|
||||
</ul>
|
||||
<div style="margin: 2rem 0; text-align: center;">
|
||||
<ThemeToggleButton client:idle />
|
||||
<ThemeToggleButton client:visible />
|
||||
</div>
|
||||
|
|
|
@ -181,10 +181,12 @@ export async function __renderPage({request, children, props, css}) {
|
|||
|
||||
const isLayout = (__astroContext in props);
|
||||
if(!isLayout) {
|
||||
let astroRootUIDCounter = 0;
|
||||
Object.defineProperty(props, __astroContext, {
|
||||
value: {
|
||||
pageCSS: css,
|
||||
request
|
||||
request,
|
||||
createAstroRootUID(seed) { return seed + astroRootUIDCounter++; },
|
||||
},
|
||||
writable: false,
|
||||
enumerable: false
|
||||
|
|
|
@ -202,10 +202,10 @@ export function __astro_component(Component: any, metadata: AstroComponentMetada
|
|||
}
|
||||
|
||||
// If we ARE hydrating this component, let's generate the hydration script
|
||||
const stringifiedProps = JSON.stringify(props);
|
||||
const astroId = hash.unique(html + stringifiedProps);
|
||||
const script = await generateHydrateScript({ instance, astroId, props }, metadata as Required<AstroComponentMetadata>);
|
||||
const astroRoot = `<astro-root uid="${astroId}">${html}</astro-root>`;
|
||||
const uniqueId = props[Symbol.for('astro.context')].createAstroRootUID(html);
|
||||
const uniqueIdHashed = hash.unique(uniqueId);
|
||||
const script = await generateHydrateScript({ instance, astroId: uniqueIdHashed, props }, metadata as Required<AstroComponentMetadata>);
|
||||
const astroRoot = `<astro-root uid="${uniqueIdHashed}">${html}</astro-root>`;
|
||||
return [astroRoot, script].join('\n');
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,12 @@ import Counter from '../components/Counter.vue'
|
|||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<Counter start="5" client:visible>Hello world!</Counter>
|
||||
<Counter start="0">SSR Rendered, No Client</Counter>
|
||||
<Counter start="1" client:load>SSR Rendered, client:load</Counter>
|
||||
<Counter start="10" client:idle>SSR Rendered, client:idle</Counter>
|
||||
<!-- Test that two client:visibles have unique uids -->
|
||||
<Counter start="100" client:visible>SSR Rendered, client:visible</Counter>
|
||||
<Counter start="1000" client:visible>SSR Rendered, client:visible</Counter>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -13,9 +13,12 @@ Vue('Can load Vue', async ({ runtime }) => {
|
|||
assert.ok(!result.error, `build error: ${result.error}`);
|
||||
|
||||
const $ = doc(result.contents);
|
||||
assert.equal($('h1').text(), 'Hello world!', 'Can use slots');
|
||||
assert.equal($('button').length, 2, 'Can render components');
|
||||
assert.equal($('pre').text(), '5', 'Can render nested components');
|
||||
const allPreValues = $('pre').toArray().map((el) => $(el).text());
|
||||
assert.equal(allPreValues, ['0', '1', '10', '100', '1000'], 'renders all components correctly');
|
||||
assert.equal($('astro-root').length, 4, 'renders 3 astro-roots');
|
||||
assert.equal($('astro-root[uid]').length, 4, 'all astro-roots have uid attributes');
|
||||
const uniqueRootUIDs = $('astro-root').map((i, el) => $(el).attr('uid'));
|
||||
assert.equal(new Set(uniqueRootUIDs).size, 4, 'all astro-roots have unique uid attributes');
|
||||
});
|
||||
|
||||
Vue.run();
|
||||
|
|
Loading…
Reference in a new issue