lambda-middlewares
Version:
Middlewares framework for AWS Lambda.
86 lines (85 loc) • 3.21 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const middleware_1 = require("./middleware");
function buildDependencyGraph(entrypoints) {
const dependencies = new Map();
const dependents = new Map();
const initialize = (middleware) => {
if (!dependencies.has(middleware)) {
dependencies.set(middleware, new Set());
}
if (!dependents.has(middleware)) {
dependents.set(middleware, new Set());
}
};
const stack = [...entrypoints];
const visited = new Set(entrypoints);
while (stack.length > 0) {
const current = stack.pop();
initialize(current);
current.dependencies.forEach((dependency) => {
initialize(dependency);
dependencies.get(current).add(dependency);
dependents.get(dependency).add(current);
if (!visited.has(dependency)) {
stack.push(dependency);
visited.add(dependency);
}
});
}
return { dependencies, dependents };
}
function topologicalSort(graph) {
const { dependencies, dependents } = graph;
const queue = [];
for (let [key, value] of dependencies.entries()) {
if (value.size === 0) {
queue.push(key);
}
}
const output = [];
while (queue.length > 0) {
const current = queue.shift();
output.push(current);
dependents.get(current).forEach((dependent) => {
dependencies.get(dependent).delete(current);
if (dependencies.get(dependent).size === 0) {
queue.push(dependent);
}
});
}
if (output.length !== dependencies.size) {
return null;
}
return output;
}
function composeMiddlewares(...entrypoints) {
const dependencyGraph = buildDependencyGraph(entrypoints);
const middlewares = topologicalSort(dependencyGraph);
if (middlewares === null) {
throw new Error('Cyclic dependency detected.');
}
;
return new middleware_1.default((handler) => {
return (event) => __awaiter(this, void 0, void 0, function* () {
const makeHandler = (i) => {
if (i >= middlewares.length) {
return handler;
}
return middlewares[i].toHandler((event) => __awaiter(this, void 0, void 0, function* () {
return yield makeHandler(i + 1)(event);
}));
};
return yield makeHandler(0)(event);
});
});
}
exports.default = composeMiddlewares;