mnfst-render 0.5.2 → 0.5.3

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.
@@ -172,6 +172,7 @@ function parseArgs() {
172
172
  if (args[i] === '--wait' && args[i + 1]) { out.wait = parseInt(args[++i], 10); continue; }
173
173
  if (args[i] === '--wait-after-idle' && args[i + 1]) { out.waitAfterIdle = parseInt(args[++i], 10); continue; }
174
174
  if (args[i] === '--concurrency' && args[i + 1]) { out.concurrency = parseInt(args[++i], 10); continue; }
175
+ if (args[i] === '--retries' && args[i + 1]) { out.retries = parseInt(args[++i], 10); continue; }
175
176
  if (args[i] === '--dry-run') { out.dryRun = true; continue; }
176
177
  if (args[i] === '--debug-prerender') { out.debugPrerender = true; continue; }
177
178
  }
@@ -231,6 +232,7 @@ function resolveConfig() {
231
232
  wait: cli.wait ?? pre.wait ?? null,
232
233
  waitAfterIdle: 0,
233
234
  concurrency: Math.max(1, cli.concurrency ?? pre.concurrency ?? Math.max(4, cpus().length - 1)),
235
+ retries: Math.max(0, cli.retries ?? pre.retries ?? 2),
234
236
  localeSubstitution: true,
235
237
  localeSubstitutionExclude: [],
236
238
  /** Explicit locale-neutral paths to render in addition to those discovered automatically.
@@ -1751,8 +1753,9 @@ async function runPrerender(config) {
1751
1753
  browser = await puppeteer.default.launch({ headless: true });
1752
1754
  }
1753
1755
 
1754
- const timeout = config.wait ?? 15000;
1756
+ const timeout = config.wait ?? 30000;
1755
1757
  const concurrency = config.concurrency;
1758
+ const maxRetries = config.retries ?? 2;
1756
1759
  const pathTotal = pathList.length;
1757
1760
  const failedPaths = [];
1758
1761
  const debugRows = [];
@@ -2721,19 +2724,34 @@ async function runPrerender(config) {
2721
2724
  }
2722
2725
  }
2723
2726
 
2724
- // Phase 1: Puppeteer — render base paths, cache raw DOM for substitution
2727
+ // Phase 1: Puppeteer — render base paths, cache raw DOM for substitution.
2728
+ // Any failures (e.g. transient navigation timeouts) are retried up to
2729
+ // `maxRetries` times with a short backoff before being reported as fatal.
2725
2730
  try {
2726
2731
  let index = 0;
2727
2732
  async function worker() {
2728
2733
  while (true) {
2729
2734
  const i = index++;
2730
2735
  if (i >= puppeteerPaths.length) return;
2731
- await processPath(puppeteerPaths[i], i, {
2732
- onRawHtml: (seg, html) => {
2733
- // Cache raw DOM snapshot for locale variant generation (NOT_FOUND_PATH excluded)
2734
- if (seg !== NOT_FOUND_PATH) baseHtmlCache.set(seg || '', html);
2735
- },
2736
- });
2736
+ const pathSeg = puppeteerPaths[i];
2737
+ let attempt = 0;
2738
+ while (true) {
2739
+ const failureCountBefore = failedPaths.length;
2740
+ await processPath(pathSeg, i, {
2741
+ onRawHtml: (seg, html) => {
2742
+ // Cache raw DOM snapshot for locale variant generation (NOT_FOUND_PATH excluded)
2743
+ if (seg !== NOT_FOUND_PATH) baseHtmlCache.set(seg || '', html);
2744
+ },
2745
+ });
2746
+ if (failedPaths.length === failureCountBefore) break; // success
2747
+ if (attempt >= maxRetries) break; // out of retries — leave the failure recorded
2748
+ // Pop the failure record and retry after a short backoff.
2749
+ failedPaths.pop();
2750
+ attempt++;
2751
+ const displayPath = pathSeg === '' ? '/' : (pathSeg === NOT_FOUND_PATH ? '/__prerender_404__' : '/' + pathSeg);
2752
+ process.stderr.write(`prerender: retrying ${displayPath} (attempt ${attempt + 1}/${maxRetries + 1})\n`);
2753
+ await new Promise((r) => setTimeout(r, 500 * attempt));
2754
+ }
2737
2755
  }
2738
2756
  }
2739
2757
  await Promise.all(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst-render",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Render Manifest sites to static HTML for SEO",
5
5
  "type": "module",
6
6
  "bin": {