UNPKG

microsite

Version:
28 lines (27 loc) 1.73 kB
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(" ")} ?`, } })))); }; }