/** * A minimal element factory for satori. * * satori consumes `{ type, props }` trees, which is exactly what JSX would * produce. Building them directly keeps the renderer out of the JSX transform * entirely: no pragma, no React import, and the same file runs unchanged under * Vitest, under `next build` and under the preview script. */ export type ElementNode = { type: string; props: Record & { children?: ElementChild }; }; export type ElementChild = ElementNode | string | number | null | false | ElementChild[]; export function h( type: string, props: Record | null, ...children: ElementChild[] ): ElementNode { const flat = children.flat(Infinity as 1).filter((child) => child !== null && child !== false); return { type, props: { ...(props ?? {}), ...(flat.length > 0 ? { children: flat.length === 1 ? flat[0] : flat } : {}), }, }; }