UNPKG

react-obsidian

Version:

Dependency injection framework for React and React Native applications

62 lines (55 loc) 2.36 kB
import graphRegistry from './registry/GraphRegistry'; import { Graph } from './Graph'; import providedPropertiesStore from '../ProvidedPropertiesStore'; import { CircularDependenciesDetector } from './CircularDependenciesDetector'; export default class PropertyRetriever { constructor(private graph: Graph) { } retrieve( property: string, receiver?: unknown, maybeDetector?: CircularDependenciesDetector, ): unknown | undefined { const mangledPropertyKey = providedPropertiesStore.getMangledProperty(this.graph, property); const circularDependenciesDetector = maybeDetector ?? new CircularDependenciesDetector(this.graph.name); if ( mangledPropertyKey && mangledPropertyKey in this.graph && circularDependenciesDetector.visit(this.graph.name, property) ) { const proxiedGraph = new Proxy(this.graph, { get(graph: Graph, dependencyName: string) { return graph.retrieve(dependencyName, receiver, circularDependenciesDetector); }, }); const resolved = Reflect.get(this.graph, mangledPropertyKey, receiver)(proxiedGraph); circularDependenciesDetector.clear(); return resolved; } if (circularDependenciesDetector.hasCircularDependencies()) { throw new Error( `Could not resolve ${circularDependenciesDetector.firstDependencyName}` + ` from ${circularDependenciesDetector.graphName} because of a circular dependency:` + ` ${circularDependenciesDetector.getDependencies().join(' -> ')}`, ); } const results = this.getFromSubgraphs(property, circularDependenciesDetector, receiver); if (results.length === 1) return results[0]; if (results.length > 1) { throw new Error( `Multiple subgraphs provide the property ${property}.` + 'You should probably provide a unique name to one of the providers: @Provide({name: \'uniqueName\')})', ); } return undefined; } private getFromSubgraphs( property: string, circularDependenciesDetector: CircularDependenciesDetector, receiver: unknown, ): unknown[] { const subgraphs = graphRegistry.getSubgraphs(this.graph); return subgraphs .map((subgraph: Graph) => subgraph.retrieve(property, receiver, circularDependenciesDetector)) .filter((result) => result !== undefined); } }