import React, { useMemo } from 'react' import { FIXME, RJT_CONFIG, RJT_CONSTANT, RJT_GENERIC_OPERATION, RJT_OPERAND_TYPE, RJT_SDUI } from '../core' import { useRJTConfig } from './context' interface Props { sdui: RJT_SDUI } export const Inflater: React.FC = ({ sdui }) => { const config = useRJTConfig() return useMemo(() => mapSDUI(sdui, config), [config, sdui]) } export const mapSDUI = ( sdui: RJT_SDUI | RJT_CONSTANT | RJT_GENERIC_OPERATION | RJT_OPERAND_TYPE, config: RJT_CONFIG, key?: number ): FIXME => { if (Array.isArray(sdui)) { return sdui.map((item, index) => mapSDUI(item, config, index)) } if (typeof sdui === 'object' && sdui !== null) { switch (sdui.type) { case '__RJT_COMPONENT__': { const Comp = config.components[sdui.name] if (Comp == null) { throw new Error(`SDUI Component ${sdui.name} not found in config !`) } const props = mapSDUI(sdui.props as FIXME, config) return } case '__RJT_ACTION__': { const action = config.actions[sdui.name] if (action == null) { throw new Error(`SDUI Action ${sdui.name} not found in config !`) } return () => action(...sdui.params) } case '__RJT_CONSTANT__': { const value = config.constants[sdui.name] return value } case '__RJT_OPERATION__': { const operation = sdui.operation switch (operation) { case '+': { const a = mapSDUI(sdui.operands[0], config) as number const b = mapSDUI(sdui.operands[1], config) as number return a + b } case '*': { return mapSDUI(sdui.operands[0], config) * mapSDUI(sdui.operands[1], config) } case '-': { return mapSDUI(sdui.operands[0], config) - mapSDUI(sdui.operands[1], config) } case '/': { return mapSDUI(sdui.operands[0], config) / mapSDUI(sdui.operands[1], config) } case 'pow': { return Math.pow(mapSDUI(sdui.operands[0], config), mapSDUI(sdui.operands[1], config)) } case 'sqrt': { return Math.sqrt(mapSDUI(sdui.operands[0], config)) } default: { throw new Error(`Unsupported operation type ${operation as string}`) } } } case '__RJT_FRAGMENT__': { return ( <> {sdui.children.map((item, index) => mapSDUI(item, config, index))} ) } default: { const obj: Record = {} for (const [key, value] of Object.entries(sdui)) { obj[key] = mapSDUI(value as RJT_SDUI, config) } return obj } } } return sdui }