mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import type { DiContainer } from "@ogre-tools/injectable";
|
|
import { getInjectable } from "@ogre-tools/injectable";
|
|
import type { Feature } from "./feature";
|
|
import {
|
|
featureContextMapInjectable,
|
|
featureContextMapInjectionToken,
|
|
} from "./feature-context-map-injectable";
|
|
|
|
export const registerFeature = (di: DiContainer, ...features: Feature[]) => {
|
|
features.forEach((feature) => {
|
|
registerFeatureRecursed(di, feature);
|
|
});
|
|
};
|
|
|
|
const registerFeatureRecursed = (
|
|
di: DiContainer,
|
|
feature: Feature,
|
|
dependedBy?: Feature
|
|
) => {
|
|
const featureContextMaps = di.injectMany(featureContextMapInjectionToken);
|
|
|
|
if (featureContextMaps.length === 0) {
|
|
di.register(featureContextMapInjectable);
|
|
}
|
|
|
|
const featureContextMap = di.inject(featureContextMapInjectable);
|
|
|
|
const existingFeatureContext = featureContextMap.get(feature);
|
|
if (
|
|
!dependedBy &&
|
|
existingFeatureContext &&
|
|
existingFeatureContext.dependedBy.size === 0
|
|
) {
|
|
throw new Error(
|
|
`Tried to register feature "${feature.id}", but it was already registered.`
|
|
);
|
|
}
|
|
|
|
const featureContext =
|
|
existingFeatureContext || createFeatureContext(feature, di);
|
|
|
|
featureContext.numberOfRegistrations++;
|
|
|
|
if (dependedBy) {
|
|
const oldNumberOfDependents =
|
|
featureContext.dependedBy.get(dependedBy) || 0;
|
|
|
|
const newNumberOfDependants = oldNumberOfDependents + 1;
|
|
featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
|
|
}
|
|
|
|
if (!existingFeatureContext) {
|
|
featureContext.register();
|
|
}
|
|
|
|
feature.dependencies?.forEach((dependency) => {
|
|
registerFeatureRecursed(di, dependency, feature);
|
|
});
|
|
};
|
|
|
|
const createFeatureContext = (feature: Feature, di: DiContainer) => {
|
|
const featureContextInjectable = getInjectable({
|
|
id: feature.id,
|
|
|
|
instantiate: (diForContextOfFeature) => ({
|
|
register: () => {
|
|
feature.register(diForContextOfFeature);
|
|
},
|
|
|
|
deregister: () => {
|
|
diForContextOfFeature.deregister(featureContextInjectable);
|
|
},
|
|
|
|
dependedBy: new Map<Feature, number>(),
|
|
|
|
numberOfRegistrations: 0,
|
|
}),
|
|
|
|
scope: true,
|
|
});
|
|
|
|
di.register(featureContextInjectable);
|
|
|
|
const featureContextMap = di.inject(featureContextMapInjectable);
|
|
const featureContext = di.inject(featureContextInjectable);
|
|
|
|
featureContextMap.set(feature, featureContext);
|
|
|
|
return featureContext;
|
|
};
|