@islands/hydration
Version:
Hydration utilities for îles
61 lines (59 loc) • 2.13 kB
JavaScript
// hydration.ts
var findById = (id) => document.getElementById(id) || console.error(`Missing #${id}, could not mount island.`);
function hydrateNow(framework, component, id, props, slots) {
const el = findById(id);
if (el) {
framework(component, id, el, props, slots);
el.setAttribute("hydrated", "");
}
}
async function resolveAndHydrate(frameworkFn, componentFn, id, props, slots) {
const [framework, component] = await Promise.all([frameworkFn(), componentFn()]);
hydrateNow(framework, component, id, props, slots);
}
function hydrateWhenIdle(framework, component, id, props, slots) {
const whenIdle = window.requestIdleCallback || setTimeout;
const cancelIdle = window.cancelIdleCallback || clearTimeout;
const idleId = whenIdle(() => resolveAndHydrate(framework, component, id, props, slots));
if (import.meta.env.DISPOSE_ISLANDS)
onDispose(id, () => cancelIdle(idleId));
}
function hydrateOnMediaQuery(framework, component, id, props, slots) {
const mediaQuery = matchMedia(props._mediaQuery);
delete props._mediaQuery;
const onChange = (fn = null) => mediaQuery.onchange = fn;
const hydrate = () => {
onChange();
resolveAndHydrate(framework, component, id, props, slots);
};
mediaQuery.matches ? hydrate() : onChange(hydrate);
if (import.meta.env.DISPOSE_ISLANDS)
onDispose(id, onChange);
}
function hydrateWhenVisible(framework, component, id, props, slots) {
const el = findById(id);
if (el) {
if (import.meta.env.DEV)
el.style.display = "initial";
const observer = new IntersectionObserver(([{ isIntersecting }]) => {
if (isIntersecting) {
stopObserver();
if (import.meta.env.DEV)
el.style.display = "";
resolveAndHydrate(framework, component, id, props, slots);
}
});
const stopObserver = () => observer.disconnect();
observer.observe(el);
if (import.meta.env.DISPOSE_ISLANDS)
onDispose(id, stopObserver);
}
}
var onDispose = (id, fn) => window.__ILE_DISPOSE__?.set(id, fn);
export {
hydrateNow,
hydrateWhenIdle,
hydrateOnMediaQuery,
hydrateWhenVisible,
onDispose
};