@hyperframes/producer 0.8.145 → 0.8.146

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/index.js CHANGED
@@ -272,7 +272,7 @@ function buildVirtualTimeShim(options) {
272
272
  const seedRandomFromFrame = options.seedRandomFromFrame === true;
273
273
  const seededRandomBlock = seedRandomFromFrame ? String.raw`
274
274
  // Seeded Math.random / crypto.getRandomValues, keyed by virtual time.
275
- // Mulberry32 — single uint32 state, deterministic, fast.
275
+ // Mulberry32: single uint32 state, deterministic, fast.
276
276
  var rngState = 0;
277
277
  function mulberry32() {
278
278
  rngState |= 0; rngState = (rngState + 0x6D2B79F5) | 0;
@@ -283,7 +283,7 @@ function buildVirtualTimeShim(options) {
283
283
  }
284
284
  function reseedRngFromTime(ms) {
285
285
  var ms32 = Math.max(0, Math.floor(Number(ms) || 0)) | 0;
286
- // Knuth's multiplicative hash + golden-ratio offset — gives a well-
286
+ // Knuth's multiplicative hash + golden-ratio offset gives a well-
287
287
  // distributed seed even for frame 0 (otherwise rngState=0 degenerates
288
288
  // the PRNG's first few outputs).
289
289
  rngState = (Math.imul(ms32, -1640531527) + 0x9E3779B9) | 0;
@@ -525,7 +525,7 @@ function buildRenderModeScript(fps) {
525
525
  };
526
526
  window.__playerReady = true;
527
527
  // Media-fallback player has no timeline to bind, so render-ready is immediate.
528
- // init.ts defers __renderReady until the timeline is bound \u2014 different runtime.
528
+ // init.ts defers __renderReady until the timeline is bound (a different runtime).
529
529
  window.__renderReady = true;
530
530
  return true;
531
531
  }
@@ -2117,7 +2117,7 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrVideoFrameSources, hdrStart
2117
2117
  if (matrix && !isTranslationOnly) {
2118
2118
  if (clipped && log) {
2119
2119
  log.debug(
2120
- `HDR clip rect on affine-transformed element ${el.id} \u2014 clip not applied (affine scissor not yet supported)`
2120
+ `HDR clip rect on affine-transformed element ${el.id}: clip not applied (affine scissor not yet supported)`
2121
2121
  );
2122
2122
  }
2123
2123
  blitRgb48leAffine(
@@ -2174,7 +2174,7 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, hdrImageTransferCache, w
2174
2174
  return;
2175
2175
  }
2176
2176
  if (el.clipRect && log) {
2177
- log.debug(`HDR clip rect on image element ${el.id} \u2014 clip not yet supported for images`);
2177
+ log.debug(`HDR clip rect on image element ${el.id}: clip not yet supported for images`);
2178
2178
  }
2179
2179
  try {
2180
2180
  if (hdrPerf) hdrPerf.hdrImageLayerBlits += 1;
@@ -4366,7 +4366,7 @@ import {
4366
4366
  function formatDowngradeWarning(outputFormat, forcedHdrWithoutSources) {
4367
4367
  const hdrSourceReason = forcedHdrWithoutSources ? "HDR was forced without detected HDR sources" : "HDR source detected";
4368
4368
  const formatReason = outputFormat === "hls" ? "HLS output is SDR-only (H.264 in MPEG-TS)" : "HDR + alpha is not supported";
4369
- return `[Render] ${hdrSourceReason}, but format is "${outputFormat}" \u2014 falling back to SDR. ${formatReason}. Use --format mp4 for HDR10 output.`;
4369
+ return `[Render] ${hdrSourceReason}, but format is "${outputFormat}", so falling back to SDR. ${formatReason}. Use --format mp4 for HDR10 output.`;
4370
4370
  }
4371
4371
  function findRenderHdrAutoPromotionTrigger(input) {
4372
4372
  for (const extracted of input.extractionResult?.extracted ?? []) {
@@ -4379,12 +4379,12 @@ function findRenderHdrAutoPromotionTrigger(input) {
4379
4379
  function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources) {
4380
4380
  if (forcedHdrWithoutSources) {
4381
4381
  input.log.warn(
4382
- "[Render] HDR forced by --hdr flag, but no HDR sources were detected \u2014 defaulting to HLG. SDR-only compositions may look perceptually wrong on HDR displays."
4382
+ "[Render] HDR forced by --hdr flag, but no HDR sources were detected, defaulting to HLG. SDR-only compositions may look perceptually wrong on HDR displays."
4383
4383
  );
4384
4384
  }
4385
4385
  if (!effectiveHdr) {
4386
4386
  input.log.info(
4387
- hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected \u2014 rendering SDR"
4387
+ hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected, rendering SDR"
4388
4388
  );
4389
4389
  return;
4390
4390
  }
@@ -4399,9 +4399,9 @@ function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources)
4399
4399
  );
4400
4400
  return;
4401
4401
  }
4402
- const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected \u2014 defaulting to HLG)" : "forced by --hdr flag";
4402
+ const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected, defaulting to HLG)" : "forced by --hdr flag";
4403
4403
  input.log.info(
4404
- `[Render] HDR ${reason} \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
4404
+ `[Render] HDR ${reason}, output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
4405
4405
  );
4406
4406
  }
4407
4407
  function resolveEffectiveHdrMode(input) {
@@ -4497,14 +4497,14 @@ function resolveRenderWorkerCount(totalFrames, requestedWorkers, cfg, compiled,
4497
4497
  const reasonCodes = new Set(compiled.renderModeHints.reasons.map((r) => r.code));
4498
4498
  if (reasonCodes.has("htmlInCanvas")) {
4499
4499
  log.warn(
4500
- "[Render] html-in-canvas (drawElementImage) detected \u2014 pinning to 1 worker (Chrome concurrency limitation).",
4500
+ "[Render] html-in-canvas (drawElementImage) detected, pinning to 1 worker (Chrome concurrency limitation).",
4501
4501
  { requestedWorkers }
4502
4502
  );
4503
4503
  return 1;
4504
4504
  }
4505
4505
  if (cfg.lowMemoryMode && requestedWorkers === void 0) {
4506
4506
  log.info(
4507
- "[Render] Low-memory profile \u2014 pinning to 1 capture worker (auto-worker calibration skipped)."
4507
+ "[Render] Low-memory profile, pinning to 1 capture worker (auto-worker calibration skipped)."
4508
4508
  );
4509
4509
  return 1;
4510
4510
  }
@@ -5139,7 +5139,7 @@ function assertVideoFrameCoverage(reports, threshold) {
5139
5139
  const thresholdPct = (threshold * 100).toFixed(1);
5140
5140
  const suffix = sorted.length > 1 ? ` (+${sorted.length - 1} more clip(s) below threshold)` : "";
5141
5141
  throw new VideoFrameCoverageError(
5142
- `Video "${worst.videoId}" captured ${worst.capturedFrames} of expected ${worst.expectedFrames} frames (coverage ${pct}%, threshold ${thresholdPct}%). check/snapshot may pass while the encoded MP4 renders this clip blank \u2014 aborting render to prevent shipping a wrong MP4.${suffix} Set HF_VIDEO_COVERAGE_THRESHOLD=0 to disable this gate.`,
5142
+ `Video "${worst.videoId}" captured ${worst.capturedFrames} of expected ${worst.expectedFrames} frames (coverage ${pct}%, threshold ${thresholdPct}%). check/snapshot may pass while the encoded MP4 renders this clip blank, so the render is aborted to prevent shipping a wrong MP4.${suffix} Set HF_VIDEO_COVERAGE_THRESHOLD=0 to disable this gate.`,
5143
5143
  { threshold, worst, failedReports: sorted }
5144
5144
  );
5145
5145
  }
@@ -6035,7 +6035,7 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
6035
6035
  if (tagName !== "video") {
6036
6036
  if (error instanceof NotMediaPayloadError2) {
6037
6037
  log?.warn(
6038
- `[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file \u2014 the element is dropped from the render. Point it at a rendered media file.`
6038
+ `[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file, so the element is dropped from the render. Point it at a rendered media file.`
6039
6039
  );
6040
6040
  }
6041
6041
  return { duration: null, resolvedPath: filePath };
@@ -6124,7 +6124,7 @@ async function compileHtmlFile(html, baseDir, downloadDir, log) {
6124
6124
  if (r.maxDuration != null && shouldClampResolvedMediaDuration(r.tagName, r.duration, r.maxDuration)) {
6125
6125
  clampList.push({ id: r.id, duration: r.maxDuration });
6126
6126
  log?.warn(
6127
- `[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s \u2014 the slot is shortened to the media length. Set data-duration to ~${r.maxDuration.toFixed(2)}s, trim data-media-start, or use a longer/looping source if that isn't intended.`
6127
+ `[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s, so the slot is shortened to the media length. Set data-duration to ~${r.maxDuration.toFixed(2)}s, trim data-media-start, or use a longer/looping source if that isn't intended.`
6128
6128
  );
6129
6129
  }
6130
6130
  }
@@ -6513,7 +6513,7 @@ ${safeText}
6513
6513
  } else {
6514
6514
  if (download.reason instanceof ScriptIntegrityError) throw download.reason;
6515
6515
  defaultLogger.warn(
6516
- `[Compiler] WARNING: Failed to download CDN script: ${src} \u2014 ${download.reason}. The render may fail if this script is required (e.g. GSAP). Consider bundling it locally in your project.`
6516
+ `[Compiler] WARNING: Failed to download CDN script: ${src} (${download.reason}). The render may fail if this script is required (e.g. GSAP). Consider bundling it locally in your project.`
6517
6517
  );
6518
6518
  }
6519
6519
  }
@@ -6565,7 +6565,7 @@ function collectExternalAssets(html, projectDir) {
6565
6565
  }
6566
6566
  if (externalAssets.size > 0) {
6567
6567
  defaultLogger.info(
6568
- `[Compiler] Found ${externalAssets.size} asset(s) outside project directory \u2014 will copy to render output`
6568
+ `[Compiler] Found ${externalAssets.size} asset(s) outside project directory, will copy to render output`
6569
6569
  );
6570
6570
  }
6571
6571
  return {
@@ -6590,7 +6590,7 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
6590
6590
  urlToLocal.set(url, localPath);
6591
6591
  } catch (err) {
6592
6592
  const identity = safeDownloadUrlIdentity(url);
6593
- defaultLogger.warn(`[Compiler] ${warnLabel} \u2014 using original URL as fallback.`, {
6593
+ defaultLogger.warn(`[Compiler] ${warnLabel}, using original URL as fallback.`, {
6594
6594
  urlFingerprint: identity.urlFingerprint,
6595
6595
  host: identity.host,
6596
6596
  error: err instanceof Error ? err.message : String(err)
@@ -6683,7 +6683,7 @@ async function fetchExternalStylesheetCss(href) {
6683
6683
  timeoutMs: 15e3
6684
6684
  });
6685
6685
  } catch (err) {
6686
- defaultLogger.warn("[Compiler] External stylesheet fetch failed \u2014 preserving link tag.", {
6686
+ defaultLogger.warn("[Compiler] External stylesheet fetch failed, preserving link tag.", {
6687
6687
  urlFingerprint: identity.urlFingerprint,
6688
6688
  host: identity.host,
6689
6689
  error: err instanceof Error ? err.message : String(err)
@@ -7327,12 +7327,15 @@ async function resolveCompositionDurations(page, unresolved) {
7327
7327
  const resolved = [];
7328
7328
  for (const id of compIds) {
7329
7329
  const tl = timelines[id];
7330
- if (tl && typeof tl.duration === "function") {
7331
- const dur = tl.duration();
7332
- if (dur > 0) {
7333
- resolved.push({ id, duration: dur, source: "__timelines" });
7334
- continue;
7335
- }
7330
+ let dur = 0;
7331
+ try {
7332
+ dur = typeof tl?.duration === "function" ? Number(tl.duration()) : 0;
7333
+ } catch {
7334
+ dur = 0;
7335
+ }
7336
+ if (dur > 0) {
7337
+ resolved.push({ id, duration: dur, source: "__timelines" });
7338
+ continue;
7336
7339
  }
7337
7340
  const el = document.getElementById(id);
7338
7341
  if (el) {
@@ -7428,28 +7431,28 @@ async function runCompileStage(input) {
7428
7431
  cfg.useDrawElement = false;
7429
7432
  deCompileGate = "3d";
7430
7433
  log.info(
7431
- "[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility) \u2014 disabling drawElementImage for this render. Capture uses the platform's baseline route."
7434
+ "[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility), so disabling drawElementImage for this render. Capture uses the platform's baseline route."
7432
7435
  );
7433
7436
  }
7434
7437
  if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_BLEND !== "true" && compiled.usesMixBlendMode) {
7435
7438
  cfg.useDrawElement = false;
7436
7439
  deCompileGate = "mix_blend_mode";
7437
7440
  log.info(
7438
- "[Render] Fast capture: composition uses mix-blend-mode \u2014 disabling drawElementImage for this render. Capture uses the platform's baseline route."
7441
+ "[Render] Fast capture: composition uses mix-blend-mode, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
7439
7442
  );
7440
7443
  }
7441
7444
  if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_ANCESTOR_BG !== "true" && compiled.hasAncestorBackgroundImage) {
7442
7445
  cfg.useDrawElement = false;
7443
7446
  deCompileGate = "ancestor_background_image";
7444
7447
  log.info(
7445
- "[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image \u2014 disabling drawElementImage for this render. Capture uses the platform's baseline route."
7448
+ "[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
7446
7449
  );
7447
7450
  }
7448
7451
  if (cfg.useDrawElement && process.env.PRODUCER_EXPERIMENTAL_FAST_CAPTURE !== "true" && compiled.hasShaderTransitions) {
7449
7452
  cfg.useDrawElement = false;
7450
7453
  deCompileGate = "shader_transitions";
7451
7454
  log.info(
7452
- "[Render] Fast capture: composition uses shader transitions \u2014 disabling drawElementImage so page-side compositing stays available."
7455
+ "[Render] Fast capture: composition uses shader transitions, so disabling drawElementImage so page-side compositing stays available."
7453
7456
  );
7454
7457
  }
7455
7458
  if (!cfg.useDrawElement && cfg.pageSideCompositingAutoDisabled) {
@@ -7777,7 +7780,7 @@ async function runProbeStage(input) {
7777
7780
  } else {
7778
7781
  beginFrameStalled = true;
7779
7782
  log.warn(
7780
- "[Render] BeginFrame liveness probe timed out \u2014 this composition stalls BeginFrame on this host (SwiftShader heavy-layer pattern). Relaunching the probe browser in screenshot capture mode; the render will use screenshot capture throughout.",
7783
+ "[Render] BeginFrame liveness probe timed out: this composition stalls BeginFrame on this host (SwiftShader heavy-layer pattern). Relaunching the probe browser in screenshot capture mode; the render will use screenshot capture throughout.",
7781
7784
  { probeTimeoutMs }
7782
7785
  );
7783
7786
  lastBrowserConsole = probeSession.browserConsoleBuffer;
@@ -7991,7 +7994,7 @@ async function runProbeStage(input) {
7991
7994
  video.start = win.visibleStart;
7992
7995
  video.end = win.visibleEnd;
7993
7996
  log.info(
7994
- `[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s\u2013${win.visibleEnd.toFixed(2)}s`
7997
+ `[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s to ${win.visibleEnd.toFixed(2)}s`
7995
7998
  );
7996
7999
  }
7997
8000
  }
@@ -8039,7 +8042,7 @@ async function runProbeStage(input) {
8039
8042
  });
8040
8043
  if (!timelinesInfo.gsapLoaded) {
8041
8044
  diagnostics.push(
8042
- "GSAP is not loaded \u2014 CDN script may have failed to download. Bundle GSAP locally in your project instead of using a CDN <script src>."
8045
+ "GSAP is not loaded. The CDN script may have failed to download. Bundle GSAP locally in your project instead of using a CDN <script src>."
8043
8046
  );
8044
8047
  } else if (timelinesInfo.timelineKeys.length === 0) {
8045
8048
  diagnostics.push(
@@ -8056,10 +8059,10 @@ async function runProbeStage(input) {
8056
8059
  log.warn("Failed to gather browser diagnostics for zero-duration composition", {
8057
8060
  error: err instanceof Error ? err.message : String(err)
8058
8061
  });
8059
- diagnostics.push("(Could not gather browser diagnostics \u2014 page may have crashed)");
8062
+ diagnostics.push("(Could not gather browser diagnostics. The page may have crashed.)");
8060
8063
  }
8061
8064
  const hint = diagnostics.length > 0 ? "\n\nDiagnostics:\n - " + diagnostics.join("\n - ") : "\n\nCheck that GSAP timelines are registered on window.__timelines.";
8062
- throw new Error("Composition duration is 0 \u2014 this would produce a black video." + hint);
8065
+ throw new Error("Composition duration is 0, so this would produce a black video." + hint);
8063
8066
  }
8064
8067
  if (probeSession) {
8065
8068
  const failedRequests = probeSession.browserConsoleBuffer.filter(isActionableProbeFailure);
@@ -8124,7 +8127,7 @@ function validateNoGpuEncode(config) {
8124
8127
  if (config.useGpu === true) {
8125
8128
  throw new PlanValidationError(
8126
8129
  BROWSER_GPU_NOT_SOFTWARE,
8127
- "[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default) \u2014 software libx264/libx265 is the only supported encoder in distributed mode."
8130
+ "[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default): software libx264/libx265 is the only supported encoder in distributed mode."
8128
8131
  );
8129
8132
  }
8130
8133
  if (config.browserGpuMode !== void 0 && config.browserGpuMode !== "software") {
@@ -8171,6 +8174,7 @@ import {
8171
8174
  detectTransfer,
8172
8175
  extractAllVideoFrames,
8173
8176
  extractMediaMetadata as extractMediaMetadata3,
8177
+ isVideoPastTimelineEnd,
8174
8178
  isHdrColorSpace as isHdrColorSpace2,
8175
8179
  resolveProjectRelativeSrc as resolveProjectRelativeSrc3,
8176
8180
  runVideoExtractionWithRetry,
@@ -8390,6 +8394,9 @@ async function runExtractVideosStage(input) {
8390
8394
  } = input;
8391
8395
  const stage2Start = Date.now();
8392
8396
  const extractionPolicy = resolveVideoExtractionPolicy();
8397
+ composition.videos = composition.videos.filter(
8398
+ (video) => !isVideoPastTimelineEnd(video, composition.duration)
8399
+ );
8393
8400
  let frameLookup = null;
8394
8401
  let extractionResult = null;
8395
8402
  let failureToEnforce = null;
@@ -8476,7 +8483,8 @@ async function runExtractVideosStage(input) {
8476
8483
  timelineEnd: composition.duration,
8477
8484
  maxTransientRetries: extractionPolicy.maxTransientRetries,
8478
8485
  collectProbeFailures: extractionPolicy.failureMode === "enforce",
8479
- deferRangeExtraction
8486
+ deferRangeExtraction,
8487
+ contentKeyedDirs: [join16(compiledDir, REMOTE_MEDIA_SUBDIR)]
8480
8488
  },
8481
8489
  abortSignal,
8482
8490
  cfg,
@@ -11102,7 +11110,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
11102
11110
  const madeProgress = captureAttemptMadeProgress(frameCount, remainingCount);
11103
11111
  if (!madeProgress) {
11104
11112
  options.log.warn(
11105
- "[Render] Capture attempt made no forward progress; composition is likely structurally broken \u2014 not retrying.",
11113
+ "[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
11106
11114
  { attempt, frameCount, remainingCount, workers: currentWorkers }
11107
11115
  );
11108
11116
  }
@@ -11171,7 +11179,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
11171
11179
  }
11172
11180
  if (!madeProgress) {
11173
11181
  options.log.warn(
11174
- "[Render] Capture attempt made no forward progress; composition is likely structurally broken \u2014 not retrying.",
11182
+ "[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
11175
11183
  { attempt, frameCount, remainingCount, workers: currentWorkers }
11176
11184
  );
11177
11185
  }
@@ -11634,7 +11642,7 @@ async function executeRenderJob(job, projectDir, outputPath, progressSink, abort
11634
11642
  execution.defer("remove workDir", () => {
11635
11643
  if (job.config.debug) return;
11636
11644
  if (job.status === "complete" && process.env.KEEP_TEMP === "1") {
11637
- log.info("KEEP_TEMP=1 \u2014 leaving workDir on disk for inspection", { workDir });
11645
+ log.info("KEEP_TEMP=1, leaving workDir on disk for inspection", { workDir });
11638
11646
  return;
11639
11647
  }
11640
11648
  rmSync9(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
@@ -11871,7 +11879,7 @@ async function executeRenderPipeline(input) {
11871
11879
  captureForceScreenshot = true;
11872
11880
  updateCaptureObservability({ forceScreenshot: captureForceScreenshot });
11873
11881
  log.info(
11874
- "[Render] Low-memory render profile active \u2014 screenshot capture, auto-worker calibration skipped" + (job.config.workers === void 0 ? ", pinned to 1 worker" : "") + ". Override with --no-low-memory-mode or PRODUCER_LOW_MEMORY_MODE=false.",
11882
+ "[Render] Low-memory render profile active: screenshot capture, auto-worker calibration skipped" + (job.config.workers === void 0 ? ", pinned to 1 worker" : "") + ". Override with --no-low-memory-mode or PRODUCER_LOW_MEMORY_MODE=false.",
11875
11883
  { totalMemMb: getSystemTotalMb(), thresholdMb: LOW_MEMORY_TOTAL_MB_THRESHOLD }
11876
11884
  );
11877
11885
  }
@@ -12439,7 +12447,7 @@ async function executeRenderPipeline(input) {
12439
12447
  cfg.useDrawElement = false;
12440
12448
  deClampReason = workerCount > 1 ? "parallel" : "disk_path";
12441
12449
  log.info(
12442
- "[Render] Fast capture: default-on drawElement disabled for this render \u2014 " + (workerCount > 1 ? "parallel capture" : "the disk capture path") + " has no runtime self-verification. Set PRODUCER_EXPERIMENTAL_FAST_CAPTURE=true to override."
12450
+ "[Render] Fast capture: default-on drawElement disabled for this render: " + (workerCount > 1 ? "parallel capture" : "the disk capture path") + " has no runtime self-verification. Set PRODUCER_EXPERIMENTAL_FAST_CAPTURE=true to override."
12443
12451
  );
12444
12452
  if (probeSession && probeSession.captureMode === "drawelement") {
12445
12453
  lastBrowserConsole = probeSession.browserConsoleBuffer;
@@ -12535,7 +12543,7 @@ async function executeRenderPipeline(input) {
12535
12543
  });
12536
12544
  updateCaptureObservability({ forceScreenshot: captureForceScreenshot });
12537
12545
  log.info(
12538
- `[Render] Page-side compositing enabled \u2014 bypassing Node-side layered shader-blend path. Engine will capture one ${needsAlpha ? "RGBA PNG" : "opaque RGB"} screenshot per output frame.`
12546
+ `[Render] Page-side compositing enabled, bypassing Node-side layered shader-blend path. Engine will capture one ${needsAlpha ? "RGBA PNG" : "opaque RGB"} screenshot per output frame.`
12539
12547
  );
12540
12548
  }
12541
12549
  const useLayeredComposite = !usePageSideCompositingForTransitions && shouldUseLayeredComposite({
@@ -13032,7 +13040,7 @@ async function executeRenderPipeline(input) {
13032
13040
  cfg.useDrawElement = false;
13033
13041
  deClampReason = deClampReason ?? "disk_path";
13034
13042
  log.info(
13035
- "[Render] Fast capture: drawElement disabled for the disk fallback \u2014 streaming encoder spawn failed and the disk path has no runtime self-verification."
13043
+ "[Render] Fast capture: drawElement disabled for the disk fallback: streaming encoder spawn failed and the disk path has no runtime self-verification."
13036
13044
  );
13037
13045
  if (probeSession && probeSession.captureMode === "drawelement") {
13038
13046
  lastBrowserConsole = probeSession.browserConsoleBuffer;
@@ -13584,10 +13592,10 @@ function validateJsonSafeValue(value, field) {
13584
13592
  walkVariables(value, field, /* @__PURE__ */ new WeakSet());
13585
13593
  }
13586
13594
  var LEAF_REJECTIONS = {
13587
- undefined: "undefined leaves are silently dropped by JSON.stringify \u2014 use null if you mean an absent value",
13595
+ undefined: "undefined leaves are silently dropped by JSON.stringify. Use null if you mean an absent value",
13588
13596
  function: "functions are not JSON-serializable",
13589
13597
  symbol: "Symbols are not JSON-serializable",
13590
- bigint: "BigInt values throw at JSON.stringify \u2014 encode as a string if you need 64-bit integers"
13598
+ bigint: "BigInt values throw at JSON.stringify. Encode as a string if you need 64-bit integers"
13591
13599
  };
13592
13600
  function walkVariables(value, path, seen) {
13593
13601
  const t = typeof value;
@@ -13608,7 +13616,7 @@ function walkVariables(value, path, seen) {
13608
13616
  if (seen.has(value)) {
13609
13617
  throw new InvalidConfigError(
13610
13618
  path,
13611
- "circular reference detected \u2014 JSON.stringify cannot serialize cycles"
13619
+ "circular reference detected: JSON.stringify cannot serialize cycles"
13612
13620
  );
13613
13621
  }
13614
13622
  seen.add(value);
@@ -14299,7 +14307,7 @@ function validateOutputResolutionOverride(body) {
14299
14307
  return `Invalid outputResolution "${body.outputResolution}". Must be one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k (aliases: 1080p, 4k, \u2026).`;
14300
14308
  }
14301
14309
  if (normalized !== void 0 && (body.format === "webm" || body.format === "mov")) {
14302
- return `outputResolution is not supported with format "${body.format}" \u2014 the alpha (webm/mov) capture path can't supersample. Use format "mp4", or omit outputResolution to render at the composition's native dimensions.`;
14310
+ return `outputResolution is not supported with format "${body.format}": the alpha (webm/mov) capture path can't supersample. Use format "mp4", or omit outputResolution to render at the composition's native dimensions.`;
14303
14311
  }
14304
14312
  return void 0;
14305
14313
  }
@@ -15024,7 +15032,7 @@ function collectPlanAssetShas(planDir) {
15024
15032
  }
15025
15033
  if (compositionHtml === null) {
15026
15034
  throw new Error(
15027
- `[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH} \u2014 upstream compile stage did not materialize the expected file.`
15035
+ `[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH} (upstream compile stage did not materialize the expected file).`
15028
15036
  );
15029
15037
  }
15030
15038
  return { compositionHtml, assets };
@@ -15607,7 +15615,7 @@ var PlanTooLargeError = class extends Error {
15607
15615
  const breakdownSuffix = breakdown ? ` Breakdown: video-frames=${formatBytes(breakdown.videoFramesBytes)}, compiled=${formatBytes(breakdown.compiledBytes)} (source-media=${formatBytes(breakdown.sourceMediaBytes)}), audio=${formatBytes(breakdown.audioBytes)}, metadata=${formatBytes(breakdown.metadataBytes)}, other=${formatBytes(breakdown.otherBytes)}, files=${breakdown.fileCount}.` : "";
15608
15616
  const observationSuffix = observedAt ? ` Observed at ${observedAt}.` : "";
15609
15617
  super(
15610
- `[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`) \u2014 it has no planDir size cap.` + observationSuffix + breakdownSuffix
15618
+ `[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`), which has no planDir size cap.` + observationSuffix + breakdownSuffix
15611
15619
  );
15612
15620
  this.name = "PlanTooLargeError";
15613
15621
  this.sizeBytes = sizeBytes;
@@ -15624,7 +15632,7 @@ var FormatNotSupportedInDistributedError = class extends Error {
15624
15632
  reason;
15625
15633
  constructor(format, reason) {
15626
15634
  super(
15627
- `[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`) \u2014 it has full format support \u2014 or pick a distributed-supported format: mp4 SDR, mov ProRes 4444, png-sequence, or webm VP9.`
15635
+ `[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`), which has full format support, or pick a distributed-supported format: mp4 SDR, mov ProRes 4444, png-sequence, or webm VP9.`
15628
15636
  );
15629
15637
  this.name = "FormatNotSupportedInDistributedError";
15630
15638
  this.format = format;
@@ -15713,7 +15721,7 @@ async function readFontSnapshotSha() {
15713
15721
  const data = module.EMBEDDED_FONT_DATA;
15714
15722
  if (!data || typeof data !== "object") {
15715
15723
  throw new Error(
15716
- "[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data \u2014 was `bun run build:fonts` run?"
15724
+ "[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data. Was `bun run build:fonts` run?"
15717
15725
  );
15718
15726
  }
15719
15727
  const dataObj = data;
@@ -15763,7 +15771,7 @@ function resolveEncoderTriple(config) {
15763
15771
  }
15764
15772
  if (config.codec !== void 0) {
15765
15773
  throw new Error(
15766
- `[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats \u2014 mov is always ProRes 4444, webm is always libvpx-vp9, and png-sequence has no encoder.`
15774
+ `[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats: mov is always ProRes 4444, webm is always libvpx-vp9, and png-sequence has no encoder.`
15767
15775
  );
15768
15776
  }
15769
15777
  return resolveNonMp4EncoderTriple(config.format, config.quality ?? "standard");