Skip to content

Instantly share code, notes, and snippets.

@arleighdickerson
Created December 12, 2024 17:52
Show Gist options
  • Save arleighdickerson/7d6e1364b0a25c15f9cff47d84fb37f8 to your computer and use it in GitHub Desktop.
Save arleighdickerson/7d6e1364b0a25c15f9cff47d84fb37f8 to your computer and use it in GitHub Desktop.
inversify-provider.tsx
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