Simplify nested hydration flow (#7370)
This commit is contained in:
parent
da56a005d9
commit
83016795e9
5 changed files with 24 additions and 51 deletions
5
.changeset/gorgeous-tables-sparkle.md
Normal file
5
.changeset/gorgeous-tables-sparkle.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Simplify nested hydration flow
|
4
.github/scripts/bundle-size.mjs
vendored
4
.github/scripts/bundle-size.mjs
vendored
|
@ -23,7 +23,9 @@ export default async function checkBundleSize({ github, context }) {
|
|||
...context.repo,
|
||||
pull_number: PR_NUM,
|
||||
});
|
||||
const clientRuntimeFiles = files.filter(({ filename }) => filename.startsWith(CLIENT_RUNTIME_PATH));
|
||||
const clientRuntimeFiles = files.filter((file) => {
|
||||
return file.filename.startsWith(CLIENT_RUNTIME_PATH) && file.status !== 'removed'
|
||||
});
|
||||
if (clientRuntimeFiles.length === 0) return;
|
||||
|
||||
const table = [
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
const HYDRATE_KEY = `astro:hydrate`;
|
||||
function debounce<T extends (...args: any[]) => any>(cb: T, wait = 20) {
|
||||
let h = 0;
|
||||
let callable = (...args: any) => {
|
||||
clearTimeout(h);
|
||||
h = setTimeout(() => cb(...args), wait) as unknown as number;
|
||||
};
|
||||
return callable as T;
|
||||
}
|
||||
|
||||
export const notify = debounce(() => {
|
||||
window.dispatchEvent(new CustomEvent(HYDRATE_KEY));
|
||||
});
|
||||
|
||||
if (!(window as any)[HYDRATE_KEY]) {
|
||||
if ('MutationObserver' in window) {
|
||||
new MutationObserver(notify).observe(document.body, { subtree: true, childList: true });
|
||||
}
|
||||
(window as any)[HYDRATE_KEY] = true;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro';
|
||||
|
||||
type DirectiveLoader = (get: GetHydrateCallback, opts: HydrateOptions, root: HTMLElement) => void;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Astro: {
|
||||
idle: DirectiveLoader;
|
||||
load: DirectiveLoader;
|
||||
media: DirectiveLoader;
|
||||
only: DirectiveLoader;
|
||||
visible: DirectiveLoader;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
|
@ -59,7 +59,6 @@ declare const Astro: {
|
|||
}
|
||||
}
|
||||
async childrenConnectedCallback() {
|
||||
window.addEventListener('astro:hydrate', this.hydrate);
|
||||
let beforeHydrationUrl = this.getAttribute('before-hydration-url');
|
||||
if (beforeHydrationUrl) {
|
||||
await import(beforeHydrationUrl);
|
||||
|
@ -96,17 +95,22 @@ declare const Astro: {
|
|||
this
|
||||
);
|
||||
}
|
||||
hydrate = () => {
|
||||
if (
|
||||
!this.hydrator ||
|
||||
// Make sure the island is mounted on the DOM before hydrating. It could be unmounted
|
||||
// when the parent island hydrates and re-creates this island.
|
||||
!this.isConnected ||
|
||||
// Wait for parent island to hydrate first so we hydrate top-down.
|
||||
this.parentElement?.closest('astro-island[ssr]')
|
||||
) {
|
||||
hydrate = async () => {
|
||||
// The client directive needs to load the hydrator code before it can hydrate
|
||||
if (!this.hydrator) return;
|
||||
|
||||
// Make sure the island is mounted on the DOM before hydrating. It could be unmounted
|
||||
// when the parent island hydrates and re-creates this island.
|
||||
if (!this.isConnected) return;
|
||||
|
||||
// Wait for parent island to hydrate first so we hydrate top-down. The `ssr` attribute
|
||||
// represents that it has not completed hydration yet.
|
||||
const parentSsrIsland = this.parentElement?.closest('astro-island[ssr]');
|
||||
if (parentSsrIsland) {
|
||||
parentSsrIsland.addEventListener('astro:hydrate', this.hydrate, { once: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const slotted = this.querySelectorAll('astro-slot');
|
||||
const slots: Record<string, string> = {};
|
||||
// Always check to see if there are templates.
|
||||
|
@ -126,12 +130,11 @@ declare const Astro: {
|
|||
const props = this.hasAttribute('props')
|
||||
? JSON.parse(this.getAttribute('props')!, reviver)
|
||||
: {};
|
||||
this.hydrator(this)(this.Component, props, slots, {
|
||||
await this.hydrator(this)(this.Component, props, slots, {
|
||||
client: this.getAttribute('client'),
|
||||
});
|
||||
this.removeAttribute('ssr');
|
||||
window.removeEventListener('astro:hydrate', this.hydrate);
|
||||
window.dispatchEvent(new CustomEvent('astro:hydrate'));
|
||||
this.dispatchEvent(new CustomEvent('astro:hydrate'));
|
||||
};
|
||||
attributeChangedCallback() {
|
||||
this.hydrate();
|
||||
|
|
Loading…
Reference in a new issue