98 lines
5.9 KiB
Plaintext
98 lines
5.9 KiB
Plaintext
"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 |