import { createElement , ReactChild , ReactElement , ReactNode , ReactType } from 'react' ; const { assign } = Object ; const { isArray } = Array ; export type ArgumentTransformation = ( arg : any ) => any ; export const NJSXConfig = { argumentTransformations : [ ] , dynamicSelectorHandler : ( name ) => { throw new TypeError ( `Can't refine by ${ name }: No handler for dynamic selector was provided` ) ; } , } ; export interface Builder < P > { ( ) : ReactElement < P > ; ( head , ... tail ) : Builder < P > ; readonly [ key ] : Builder < P > ; } export type BuilderArgument < P > = BuilderRefinement < P > | undefined | null | boolean | ReactChild | ( ( ) => ReactElement < any > ) | Partial < P > | BuilderArgumentArray < P > ; export interface BuilderArgumentArray < P > extends Array < BuilderArgument < P > > { } export type BuilderState < P > = Partial < P & { children : ReactNode [ ] ; } > ; export type BuilderRefinement < P > = ( state : BuilderState < P > ) => BuilderState < P > ; export type NJSX = < P > ( type : ReactType < P > ) => Builder < P > ; const njsx = < P > ( type , baseState = { } ) : Builder < P > => { const builder = ( ( ... args ) => ! args . length ? createElement ( type , baseState as P , ... baseState . children || [ ] ) : njsx ( type , args . reduce < BuilderState < P > > ( applyArgument , baseState ) ) ) as Builder < P > ; ( builder as any ) . __isNJSXBuilder__ = true ; return ! NJSXConfig . dynamicSelectorHandler ? builder : new Proxy ( builder , { get ( target , name ) { if ( name === '__isNJSXBuilder__' ) return target . __isNJSXBuilder__ ; return target ( NJSXConfig . dynamicSelectorHandler ! ( name . toString ( ) ) ) ; } , } ) ; } ; function applyArgument < P > ( state , baseArg ) { const arg = NJSXConfig . argumentTransformations . reduce ( ( s , tx ) => tx ( s ) , baseArg ) ; if ( isIgnored ( arg ) ) return state ; if ( isArray ( arg ) ) return arg . reduce ( applyArgument , state ) ; if ( isBuilder ( arg ) ) return addChild ( state , arg ( ) ) ; if ( isChild ( arg ) ) return addChild ( state , arg ) ; if ( typeof arg === 'object' ) return assign ( { } , state , arg ) ; if ( typeof arg === 'function' ) return arg ( state ) ; throw new TypeError ( `Unsupported NJSX argument: ${ arg }` ) ; } function isBuilder ( target ) { return target . __isNJSXBuilder__ ; } function isIgnored ( target ) { return target === null || target === undefined || typeof target === 'boolean' ; } function isChild ( target ) { return typeof target === 'number' || typeof target === 'string' || typeof target === 'object' && ! ! target . type ; } function addChild < P > ( state , child ) { return assign ( { } , state , { children : [ ... state . children || [ ] , child ] } ) ; } export default njsx as NJSX ;