@nmakarov/cli-toolkit 0.78.0 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/init.cjs CHANGED
@@ -2668,13 +2668,14 @@ var Logger = class _Logger {
2668
2668
  */
2669
2669
  progress(message, opts) {
2670
2670
  const { prefix, count, total } = opts;
2671
- const paddedTotal = String(total).length;
2671
+ const displayTotal = Math.max(Number(total) || 0, Number(count) || 0);
2672
+ const paddedTotal = String(displayTotal).length;
2672
2673
  const paddedCount = String(count).padStart(paddedTotal, " ");
2673
2674
  const payload = {
2674
2675
  level: "progress",
2675
2676
  message,
2676
2677
  count: paddedCount,
2677
- total,
2678
+ total: displayTotal,
2678
2679
  prefix
2679
2680
  };
2680
2681
  const key = prefix ?? "";
@@ -2691,7 +2692,7 @@ var Logger = class _Logger {
2691
2692
  if (wantTimes) {
2692
2693
  let remaining = -1;
2693
2694
  if (itemsPerSec > 0) {
2694
- remaining = (total - count) / itemsPerSec;
2695
+ remaining = Math.max(0, (displayTotal - count) / itemsPerSec);
2695
2696
  }
2696
2697
  payload.elapsed = this.round(elapsedSeconds, 2);
2697
2698
  payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;
@@ -2700,12 +2701,12 @@ var Logger = class _Logger {
2700
2701
  payload.rate = itemsPerSec >= 0 ? this.round(itemsPerSec, 2) : itemsPerSec;
2701
2702
  }
2702
2703
  }
2703
- if (count >= total) {
2704
+ if (count === total) {
2704
2705
  delete this.startTimes[key];
2705
2706
  delete this.startCounts[key];
2706
2707
  delete this.lastProgressTimes[key];
2707
2708
  }
2708
- if (this.shouldOutputProgress(prefix ?? "", count, total)) {
2709
+ if (this.shouldOutputProgress(prefix ?? "", count, displayTotal)) {
2709
2710
  this.out(payload);
2710
2711
  if (this.options.progressThrottle && prefix) {
2711
2712
  this.lastProgressTimes[prefix] = Date.now();
@@ -2864,6 +2865,8 @@ function setup(opts = {}) {
2864
2865
  // a quick "show me the figured params and quit" that skips the flow's
2865
2866
  // actual work. Like --stopAfter=init, this is a hard exit(0) (registered
2866
2867
  // cleanups are skipped); call it once components/params are resolved.
2868
+ _requestExitCode: null,
2869
+ requestExit: null,
2867
2870
  showUsedParamsIfNeeded: () => {
2868
2871
  const mode = params.getShowUsedParamsMode?.();
2869
2872
  if (mode !== "top" && mode !== "stop") return;
@@ -2874,6 +2877,9 @@ function setup(opts = {}) {
2874
2877
  }
2875
2878
  }
2876
2879
  };
2880
+ context.requestExit = (code = 0) => {
2881
+ context._requestExitCode = code;
2882
+ };
2877
2883
  logger.debug("[setup] completed successfully");
2878
2884
  return context;
2879
2885
  }
@@ -2909,9 +2915,25 @@ async function init(flow, opts = {}) {
2909
2915
  if (cleanupRan) return;
2910
2916
  cleanupRan = true;
2911
2917
  const fns = [...ctx.cleanupFunctions].reverse();
2918
+ const budgetMs = 5e3;
2919
+ const started = Date.now();
2912
2920
  for (const fn of fns) {
2921
+ const left = budgetMs - (Date.now() - started);
2922
+ if (left <= 0) {
2923
+ ctx.logger.warn("[cleanup] budget exhausted \u2014 skipping remaining cleanup");
2924
+ break;
2925
+ }
2913
2926
  try {
2914
- await fn(ctx);
2927
+ await Promise.race([
2928
+ Promise.resolve(fn(ctx)),
2929
+ new Promise((_, reject) => {
2930
+ const t = setTimeout(
2931
+ () => reject(new Error(`cleanup timed out after ${left}ms`)),
2932
+ left
2933
+ );
2934
+ t.unref?.();
2935
+ })
2936
+ ]);
2915
2937
  } catch (error) {
2916
2938
  ctx.logger.warn("[cleanup] error in cleanup function:", error);
2917
2939
  }
@@ -3007,6 +3029,8 @@ async function init(flow, opts = {}) {
3007
3029
  process.exit(process.exitCode);
3008
3030
  } else if (stop || kill) {
3009
3031
  process.exit(0);
3032
+ } else if (context._requestExitCode != null) {
3033
+ process.exit(context._requestExitCode);
3010
3034
  }
3011
3035
  }
3012
3036
  }