kist
Version:
Lightweight Package Pipeline Processor with Plugin Architecture
131 lines • 5.85 kB
JavaScript
import { __awaiter } from "tslib";
import { AbstractProcess } from "../abstract/AbstractProcess.js";
import { FileCache } from "../cache/FileCache.js";
import { BuildCache } from "../cache/BuildCache.js";
import { ProgressReporter } from "../progress/ProgressReporter.js";
import { Stage } from "./Stage.js";
export class Pipeline extends AbstractProcess {
constructor(config) {
super();
this.config = config;
this.stages = config.stages.map((stage) => new Stage(stage));
this.options = config.options;
this.logInfo("Pipeline instance created.");
}
run() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const startTime = performance.now();
this.logInfo("Starting pipeline execution...");
yield this.initializeCaching();
this.initializeProgress();
const completedStages = new Set();
try {
this.logDebug("Pipeline execution started with debug logging.");
(_a = this.progress) === null || _a === void 0 ? void 0 : _a.start();
const stagePromises = this.stages.map((stage, index) => stage.execute(completedStages).then(() => {
var _a;
(_a = this.progress) === null || _a === void 0 ? void 0 : _a.increment();
}));
yield this.runWithConcurrencyControl(stagePromises);
(_b = this.progress) === null || _b === void 0 ? void 0 : _b.finish();
yield this.saveCaches();
const duration = performance.now() - startTime;
this.logInfo(`Pipeline execution completed successfully in ${this.formatDuration(duration)}.`);
this.reportCacheStats();
}
catch (error) {
(_c = this.progress) === null || _c === void 0 ? void 0 : _c.cancel();
this.logError("Pipeline execution failed:", error);
yield this.saveCaches();
if (((_d = this.options) === null || _d === void 0 ? void 0 : _d.haltOnFailure) !== false) {
this.logError("Halting pipeline due to failure.");
process.exit(1);
}
else {
this.logWarn("Continuing pipeline execution despite errors.");
}
}
});
}
initializeCaching() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const cacheOptions = (_a = this.options) === null || _a === void 0 ? void 0 : _a.cache;
if (!(cacheOptions === null || cacheOptions === void 0 ? void 0 : cacheOptions.enabled)) {
return;
}
this.logInfo("Initializing build cache...");
this.fileCache = FileCache.getInstance({
cacheDir: cacheOptions.cacheDir,
ttl: cacheOptions.ttl,
});
yield this.fileCache.initialize();
this.buildCache = BuildCache.getInstance({
cacheDir: cacheOptions.cacheDir,
maxCacheSize: cacheOptions.maxCacheSize,
ttl: cacheOptions.ttl,
});
yield this.buildCache.initialize();
this.logDebug("Build cache initialized.");
});
}
initializeProgress() {
var _a;
const perfOptions = (_a = this.options) === null || _a === void 0 ? void 0 : _a.performance;
if ((perfOptions === null || perfOptions === void 0 ? void 0 : perfOptions.showProgress) === false) {
return;
}
this.progress = new ProgressReporter({
total: this.stages.length,
label: "Pipeline",
showPercentage: true,
showEta: true,
});
}
saveCaches() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
yield Promise.all([(_a = this.fileCache) === null || _a === void 0 ? void 0 : _a.save(), (_b = this.buildCache) === null || _b === void 0 ? void 0 : _b.save()]);
});
}
reportCacheStats() {
if (this.fileCache) {
const stats = this.fileCache.getStats();
this.logDebug(`File cache: ${stats.size} entries, ${stats.hitRate} hit rate`);
}
if (this.buildCache) {
const stats = this.buildCache.getStats();
this.logDebug(`Build cache: ${stats.size} entries, ${stats.hitRate} hit rate`);
}
}
formatDuration(ms) {
if (ms < 1000) {
return `${Math.round(ms)}ms`;
}
if (ms < 60000) {
return `${(ms / 1000).toFixed(2)}s`;
}
const minutes = Math.floor(ms / 60000);
const seconds = ((ms % 60000) / 1000).toFixed(1);
return `${minutes}m ${seconds}s`;
}
runWithConcurrencyControl(stagePromises) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const maxConcurrentStages = ((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.performance) === null || _b === void 0 ? void 0 : _b.maxConcurrentStages) ||
((_c = this.options) === null || _c === void 0 ? void 0 : _c.maxConcurrentStages) ||
stagePromises.length;
const executingStages = new Set();
for (const stagePromise of stagePromises) {
executingStages.add(stagePromise);
stagePromise.finally(() => executingStages.delete(stagePromise));
if (executingStages.size >= maxConcurrentStages) {
yield Promise.race(executingStages);
}
}
yield Promise.all(executingStages);
});
}
}
//# sourceMappingURL=Pipeline.js.map