Created
December 12, 2024 17:52
-
-
Save arleighdickerson/7d6e1364b0a25c15f9cff47d84fb37f8 to your computer and use it in GitHub Desktop.
inversify-provider.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AsyncContainerModule, Container as ContainerImpl, ContainerModule } from 'inversify'; | |
import { Provider as IocProvider } from 'inversify-react'; | |
import _ from 'lodash'; | |
import { PropsWithChildren, useEffect, useState } from 'react'; | |
const context = require.context('src', true, /\.config\.ts$|\.config\.tsx$|\.saga\.ts|\.events\.ts$/, 'lazy-once'); | |
const keys = context.keys(); | |
const getApplicationContext = _.once(async () => { | |
const container = new ContainerImpl({ defaultScope: 'Request' }); | |
for (let i = 0; i < keys.length; i += 1) { | |
const key = keys[i]; | |
if (process.env.NODE_ENV === 'development') { | |
console.debug(`[inversify-provider] found config module ${key}`); | |
} | |
const object = await context(key); | |
if (!_.has(object, 'autoconfigure')) { | |
if (process.env.NODE_ENV === 'development') { | |
console.warn( | |
`[inversify-provider] config module ${await context.resolve(key)} does not export { autoconfigure }`, | |
); | |
} | |
continue; | |
} | |
const configuration = await object.autoconfigure; | |
if (configuration instanceof ContainerModule) { | |
container.load(configuration); | |
continue; | |
} | |
if (configuration instanceof AsyncContainerModule) { | |
await container.loadAsync(configuration); | |
continue; | |
} | |
throw new Error( | |
`module ${await context.resolve( | |
key, | |
)} appears to be a container configuration but its export { autoconfigure } is of an unrecognizable type`, | |
); | |
} | |
return container; | |
}); | |
let cancelToken: any = null; | |
const InversifyProvider = ({ children }: PropsWithChildren<{ loading: boolean }>) => { | |
const [state, setState] = useState<any>(undefined); | |
useEffect(() => { | |
getApplicationContext().then( | |
res => { | |
cancelToken = setImmediate(() => { | |
setState(res); | |
}); | |
}, | |
reason => { | |
console.warn(reason); | |
}, | |
); | |
return () => { | |
if (cancelToken !== null) { | |
clearImmediate(cancelToken); | |
cancelToken = null; | |
} | |
}; | |
}, []); | |
if (!state) { | |
return typeof children === 'function' ? children({ loading: true }) : <>{children}</>; | |
} | |
return ( | |
<IocProvider standalone={false} container={state}> | |
{typeof children === 'function' ? children({ loading: false }) : <>{children}</>} | |
</IocProvider> | |
); | |
}; | |
Object.defineProperty(InversifyProvider, 'defaultProps', { | |
configurable: false, | |
enumerable: false, | |
writable: false, | |
value: { | |
loading: null, | |
}, | |
}); | |
export default InversifyProvider; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment