Skip to content

Instantly share code, notes, and snippets.

@reggi
Created November 10, 2022 05:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reggi/36e4fea1fab3d171c547a07a62608a71 to your computer and use it in GitHub Desktop.
Save reggi/36e4fea1fab3d171c547a07a62608a71 to your computer and use it in GitHub Desktop.
import { JSX, ComponentChild, VNode } from "https://esm.sh/v96/preact@10.11.2"
import render from 'preact-render-to-string'
// you need a way to ignore the type error for an async component
const asyncComponent = (component: (props: any) => Promise<JSX.Element>): (props: any) => JSX.Element => {
return component as any
}
const Alice = asyncComponent(async (props: { children: ComponentChild}) => {
const x = await Promise.resolve('Alice')
return <div data-alice={true}>{x}</div>
})
const Foo = () => {
return <div>Foo</div>
}
const Bar = asyncComponent(async function Bar (props: { children: ComponentChild}) {
const x = await Promise.resolve('example')
return <div data-bar={true}>Bar {x}<Foo/>{props.children}<Alice></Alice></div>
})
const Example = () => {
return <div><Bar>Hello</Bar></div>
}
async function asyncComponentToSync (v: JSX.Element) {
const recursion = async (children:JSX.Element['props']['children']): Promise<any> => {
if (Array.isArray(children)) {
return await Promise.all(children.map(async (child: JSX.Element) => {
return await recursion(child)
}))
} else if (typeof children.type == 'function') {
const nnode = await children.type(children.props)
return await recursion(nnode)
} else if (typeof children == 'string') {
return children
} else if (children.props && children.props.children) {
children.props.children = await recursion(children.props.children)
return children
}
return children
}
return await recursion(v)
}
const value = await asyncComponentToSync(Example())
// console.log(JSON.stringify(value, null, 2))
console.log(render(value))
// <div>
// <div data-bar>
// Bar example
// <div>Foo</div>
// Hello
// <div data-alice>Alice</div>
// </div>
// </div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment