microsite
Version:
<br /> <br />
28 lines (27 loc) • 1.73 kB
JavaScript
import { h, createContext } from "preact";
import { useContext } from "preact/hooks";
const isServer = typeof window === "undefined";
export const HydrateContext = createContext(false);
const encode = (str) => Buffer.from(str).toString("base64");
export function withHydrate(Component, hydrationProps = {}) {
const innerName = Component.name;
const { method, fallback: Fallback } = hydrationProps;
return function (props, ref) {
const hydrateParent = useContext(HydrateContext);
if (hydrateParent)
throw new Error(`withHydrate() should only be called at the top-level of a Component tree. <${innerName} /> should not be nested within <${hydrateParent} />`);
if (props.children && !["string", "number"].includes(typeof props.children))
throw new Error(`withHydrate() is unable to serialize complex \`children\`. Please inline these children into <${innerName} />.`);
const p = isServer ? `p=${encode(JSON.stringify(props))}` : "";
const m = isServer && method ? `m=${method}` : "";
const f = isServer && typeof Fallback !== "undefined" ? "f=1" : "";
const Marker = "hydrate-marker";
const Placeholder = "hydrate-placeholder";
return (h(HydrateContext.Provider, { value: innerName },
isServer && (h(Marker, { dangerouslySetInnerHTML: { __html: `?h c=${innerName} ?` } })),
typeof Fallback !== "undefined" ? (Fallback || h(Placeholder, null)) : (h(Component, Object.assign({}, Object.assign(Object.assign({}, props), { ref })))),
isServer && (h(Marker, { dangerouslySetInnerHTML: {
__html: `?h ${[p, m, f].filter((v) => v).join(" ")} ?`,
} }))));
};
}