import { createElement, VNode } from "preact"; export type StateFunc = (p: S) => VNode; export type StateViewMap = { [S in StateType as S["status"]]: StateFunc; }; export type RecursiveState = S | (() => RecursiveState); export function compose( hook: (p: PType) => RecursiveState, viewMap: StateViewMap, ): (p: PType) => VNode { function withHook(stateHook: () => RecursiveState): () => VNode { function ComposedComponent(): VNode { const state = stateHook(); if (typeof state === "function") { const subComponent = withHook(state); return createElement(subComponent, {}); } const statusName = state.status as unknown as SType["status"]; const viewComponent = viewMap[statusName] as unknown as StateFunc; return createElement(viewComponent, state); } return ComposedComponent; } return (p: PType) => { const h = withHook(() => hook(p)); return h(); }; }