UNPKG

@inversifyjs/core

Version:

InversifyJs core package

98 lines 6.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addServiceNodeBindingIfContextFree = addServiceNodeBindingIfContextFree; const BindingConstraintsImplementation_1 = require("../../binding/models/BindingConstraintsImplementation"); const isStackOverflowError_1 = require("../../error/calculations/isStackOverflowError"); const InversifyCoreError_1 = require("../../error/models/InversifyCoreError"); const InversifyCoreErrorKind_1 = require("../../error/models/InversifyCoreErrorKind"); const LazyPlanServiceNode_1 = require("../models/LazyPlanServiceNode"); const curryBuildServiceNodeBindings_1 = require("./curryBuildServiceNodeBindings"); const curryLazyBuildPlanServiceNodeFromClassElementMetadata_1 = require("./curryLazyBuildPlanServiceNodeFromClassElementMetadata"); const curryLazyBuildPlanServiceNodeFromResolvedValueElementMetadata_1 = require("./curryLazyBuildPlanServiceNodeFromResolvedValueElementMetadata"); const currySubplan_1 = require("./currySubplan"); const plan_1 = require("./plan"); const subplan = (0, currySubplan_1.currySubplan)(plan_1.buildPlanServiceNodeFromClassElementMetadata, plan_1.buildPlanServiceNodeFromResolvedValueElementMetadata, circularLazyBuildPlanServiceNodeFromClassElementMetadata, circularLazyBuildPlanServiceNodeFromResolvedValueElementMetadata); const buildServiceNodeBindings = (0, curryBuildServiceNodeBindings_1.curryBuildServiceNodeBindings)(subplan); const lazyBuildPlanServiceNodeFromClassElementMetadata = (0, curryLazyBuildPlanServiceNodeFromClassElementMetadata_1.curryLazyBuildPlanServiceNodeFromClassElementMetadata)(buildServiceNodeBindings); const lazyBuildPlanServiceNodeFromResolvedValueElementMetadata = (0, curryLazyBuildPlanServiceNodeFromResolvedValueElementMetadata_1.curryLazyBuildPlanServiceNodeFromResolvedValueElementMetadata)(buildServiceNodeBindings); function circularLazyBuildPlanServiceNodeFromClassElementMetadata(params, bindingConstraintsList, elementMetadata) { return lazyBuildPlanServiceNodeFromClassElementMetadata(params, bindingConstraintsList, elementMetadata); } function circularLazyBuildPlanServiceNodeFromResolvedValueElementMetadata(params, bindingConstraintsList, elementMetadata) { return lazyBuildPlanServiceNodeFromResolvedValueElementMetadata(params, bindingConstraintsList, elementMetadata); } /** * Attach a binding to a service node if the binding is context-free. * @param params The plan parameters. * @param serviceNode The service node to attach the binding to. * @param binding The binding to attach. * @param bindingConstraintsList The list of binding constraints. * @param chainedBindings Whether the bindings are chained. * @returns True if the binding requires ancestor metadata, false otherwise. */ function addServiceNodeBindingIfContextFree(params, serviceNode, binding, bindingConstraintsList, chainedBindings) { if (LazyPlanServiceNode_1.LazyPlanServiceNode.is(serviceNode) && !serviceNode.isExpanded()) { return { isContextFreeBinding: true, shouldInvalidateServiceNode: false, }; } const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(bindingConstraintsList.last); if (!binding.isSatisfiedBy(bindingConstraints) || bindingConstraintsList.last.elem.getAncestorsCalled) { return { isContextFreeBinding: !bindingConstraintsList.last.elem.getAncestorsCalled, shouldInvalidateServiceNode: false, }; } return addServiceNodeSatisfiedBindingIfContextFree(params, serviceNode, binding, bindingConstraintsList, chainedBindings); } function addServiceNodeSatisfiedBindingIfContextFree(params, serviceNode, binding, bindingConstraintsList, chainedBindings) { let serviceNodeBinding; try { [serviceNodeBinding] = buildServiceNodeBindings(params, bindingConstraintsList, [binding], serviceNode, chainedBindings); } catch (error) { if ((0, isStackOverflowError_1.isStackOverflowError)(error)) { /** * We could potentially detect if we managed to traverse at least one iteration of the circular dependency loop. * If so, the binding is context free if and only if bindingConstraintsList.last.elem.getAncestorsCalled is false. * * Having said that, computing this does not solve an underlying issue with circular dependencies: further cache * refreshes are likely to encounter the same issue again and again. Recovering from stack overflow errors constantly * is not feasible, so we prefer to declare the binding as non context free, asking for a more aggressive cache * invalidation strategy, which is likely to be a cache clear. */ return { isContextFreeBinding: false, shouldInvalidateServiceNode: true, }; } throw error; } return addServiceNodeBindingNodeIfContextFree(serviceNode, serviceNodeBinding); } function addServiceNodeBindingNodeIfContextFree(serviceNode, serviceNodeBinding) { if (Array.isArray(serviceNode.bindings)) { serviceNode.bindings.push(serviceNodeBinding); } else { if (serviceNode.bindings === undefined) { serviceNode.bindings = serviceNodeBinding; } else { if (!LazyPlanServiceNode_1.LazyPlanServiceNode.is(serviceNode)) { throw new InversifyCoreError_1.InversifyCoreError(InversifyCoreErrorKind_1.InversifyCoreErrorKind.planning, 'Unexpected non-lazy plan service node. This is likely a bug in the planning logic. Please, report this issue'); } return { isContextFreeBinding: true, shouldInvalidateServiceNode: true, }; } } return { isContextFreeBinding: true, shouldInvalidateServiceNode: false, }; } //# sourceMappingURL=addServiceNodeBindingIfContextFree.js.map