import React , { createContext , ComponentType , PropsWithChildren } from 'react' ; import { DependencyCollection } from '../collection' ; import { Injector } from '../injector' ; interface InjectionContextValue { injector : Injector | null ; } export const InjectionContext = createContext < InjectionContextValue > ( { injector : null } ) ; InjectionContext . displayName = 'InjectionContext' ; const InjectionConsumer = InjectionContext . Consumer ; const InjectionProvider = InjectionContext . Provider ; export interface InjectionProviderProps { collection ? : DependencyCollection ; injector ? : Injector ; } /**
 * the React binding of wedi
 *
 * it uses the React context API to specify injection positions and
 * layered injector tree
 *
 * ```tsx
 * <Provider collection={}>
 *   { children }
 * </Provider>
 * ```
 */ export function Provider ( props ) { const { collection , children , injector } = props ; return ( < InjectionConsumer > { ( context ) => { const parentInjector = context . injector ; if ( ! ! collection === ! ! injector ) { throw new Error ( '[wedi] should provide a collection or an injector to "Provider".' ) ; } const finalInjector = injector || parentInjector ?. createChild ( collection ) || new Injector ( collection ! ) ; return ( < InjectionProvider value = { { injector : finalInjector } } > { children } < /InjectionProvider>); } } < /InjectionConsumer>); } /**
 * return a HOC that enable functional component to add injector
 * in a convenient way
 */ export function connectProvider < T > ( Comp , options ) { const { injector , collection } = options ; return function ComponentWithInjector ( props ) { return ( < Provider injector = { injector } collection = { collection } > < Comp { ... props } / > < /Provider>); } ; }