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:
Fred K. Schott 2021-08-10 09:51:19 -07:00 committed by GitHub
parent 16790aee7b
commit 1350d57997
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 20 additions and 10 deletions

View file

@ -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>

View file

@ -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

View file

@ -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');
};
}

View file

@ -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>

View file

@ -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();