UNPKG

microsite

Version:
27 lines (26 loc) 1.76 kB
import { h, createContext } from "preact"; import { useContext } from "preact/hooks"; const isServer = typeof window === "undefined"; export const HydrateContext = createContext(false); export function withHydrate(Component, hydrationProps = {}) { const name = hydrationProps.displayName || Component.displayName || Component.name; const { method, fallback: Fallback } = hydrationProps; const Wrapped = (props, ref) => { const hydrateParent = useContext(HydrateContext); if (hydrateParent) throw new Error(`withHydrate() should only be called at the top-level of a Component tree. <${name} /> 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 <${name} />.`); const p = isServer ? `p=${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: name }, isServer && (h(Marker, { dangerouslySetInnerHTML: { __html: `?h c=${name} ?` } })), 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(' ')} ?` } })))); }; Object.defineProperty(Wrapped, "name", { value: name, configurable: true }); return Wrapped; }