hyperframes 0.8.40 → 0.8.41

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.
@@ -56728,7 +56728,12 @@ var init_captureFailure = __esm({
56728
56728
  /Navigation timeout of \d+ ms exceeded/i,
56729
56729
  /ECONNREFUSED/i,
56730
56730
  /net::ERR_NETWORK_CHANGED/i,
56731
- /Composition has zero duration[\s\S]*Runtime ready: false/
56731
+ /Composition has zero duration[\s\S]*Runtime ready: false/,
56732
+ // CDP can refuse a capture call outright with this exact wording; timed-out
56733
+ // variants of the same call hit PROTOCOL_TIMEOUT_PATTERNS, checked first.
56734
+ // Anchored to this literal reason (not just the CDP method) so an unrelated,
56735
+ // genuinely deterministic Page.captureScreenshot error isn't swept in too.
56736
+ /Protocol error \(Page\.captureScreenshot\): Unable to capture screenshot/i
56732
56737
  ];
56733
56738
  PROTOCOL_TIMEOUT_PATTERNS = [
56734
56739
  /Network\.enable timed out/i,
@@ -70906,6 +70911,7 @@ var init_dist3 = __esm({
70906
70911
  init_composition();
70907
70912
  init_slideshow();
70908
70913
  init_esm10();
70914
+ init_esm10();
70909
70915
  COMPOSITION_ID_IN_CSS_PATTERN = /\[data-composition-id=["']([^"']+)["']\]/g;
70910
70916
  TIMELINE_REGISTRY_INIT_PATTERN = /window\.__timelines\s*=\s*window\.__timelines\s*\|\|\s*\{\}|window\.__timelines\s*=\s*\{\}|window\.__timelines\s*\?\?=\s*\{\}/i;
70911
70917
  TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN = /window\.__timelines\s*=\s*\{\s*(?:["'][^"']+["']|[A-Za-z_$][\w$]*)\s*:/i;
@@ -74630,13 +74636,20 @@ function publishCacheEntry(entry, partialDir) {
74630
74636
  return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
74631
74637
  }
74632
74638
  }
74633
- function touchCacheEntry(entry) {
74639
+ function touchCacheDir(dir) {
74640
+ const now = /* @__PURE__ */ new Date();
74641
+ try {
74642
+ utimesSync(dir, now, now);
74643
+ } catch {
74644
+ }
74634
74645
  try {
74635
- const now = /* @__PURE__ */ new Date();
74636
- utimesSync(join10(entry.dir, COMPLETE_SENTINEL), now, now);
74646
+ utimesSync(join10(dir, COMPLETE_SENTINEL), now, now);
74637
74647
  } catch {
74638
74648
  }
74639
74649
  }
74650
+ function touchCacheEntry(entry) {
74651
+ touchCacheDir(entry.dir);
74652
+ }
74640
74653
  function isCacheLikeChild(name) {
74641
74654
  return name.startsWith(CACHE_GENERATION_PREFIX) || name.includes(".partial-");
74642
74655
  }
@@ -75260,6 +75273,10 @@ function resolveSegmentDuration(requested, mediaStart, sourceDuration) {
75260
75273
  function resolvePlayableVideoDuration(metadata) {
75261
75274
  return Number.isFinite(metadata.videoStreamDurationSeconds) && metadata.videoStreamDurationSeconds > 0 ? metadata.videoStreamDurationSeconds : metadata.durationSeconds;
75262
75275
  }
75276
+ function canHoldFinalFramePastEof(video) {
75277
+ const timelineDuration = video.end - video.start;
75278
+ return !video.loop && Number.isFinite(timelineDuration) && timelineDuration > 0;
75279
+ }
75263
75280
  function resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, sourceDuration) {
75264
75281
  const playbackRate = normalizePlaybackRate(video.playbackRate ?? 1);
75265
75282
  const withTimelineDuration = (window3, timelineDurationSeconds) => playbackRate === 1 ? window3 : { ...window3, timelineDurationSeconds };
@@ -75328,6 +75345,18 @@ function resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, s
75328
75345
  },
75329
75346
  visibleDuration
75330
75347
  );
75348
+ } else if (canHoldFinalFramePastEof(video)) {
75349
+ const logicalDuration = Math.min(sourceDuration, FINAL_FRAME_LOGICAL_DURATION_SECONDS);
75350
+ return withTimelineDuration(
75351
+ {
75352
+ compositionStart: video.start,
75353
+ mediaStart: sourceDuration - logicalDuration,
75354
+ durationSeconds: logicalDuration,
75355
+ preserveTimelineEnd: true,
75356
+ ensureFinalFrame: true
75357
+ },
75358
+ visibleDuration
75359
+ );
75331
75360
  }
75332
75361
  }
75333
75362
  return withTimelineDuration(
@@ -75352,7 +75381,10 @@ async function resolveFinalFrameExtractionWindow(videoPath, video, metadata, win
75352
75381
  );
75353
75382
  if (window3.mediaStart < finalFrameTimestamp - 1e-9) return window3;
75354
75383
  const sourceRemaining = playableDuration - video.mediaStart;
75355
- const logicalDuration = Math.min(sourceRemaining, FINAL_FRAME_LOGICAL_DURATION_SECONDS);
75384
+ const logicalDuration = Math.min(
75385
+ Math.max(sourceRemaining, window3.durationSeconds),
75386
+ FINAL_FRAME_LOGICAL_DURATION_SECONDS
75387
+ );
75356
75388
  return {
75357
75389
  compositionStart: Math.max(0, video.start),
75358
75390
  mediaStart: playableDuration - logicalDuration,
@@ -75373,7 +75405,9 @@ function resolveVideoExtractionWindow(video, metadata, timelineEnd) {
75373
75405
  `Playable video stream duration is ${playableDuration}s`
75374
75406
  );
75375
75407
  }
75376
- if (video.mediaStart >= playableDuration) {
75408
+ const requestedTimelineDuration = video.end - video.start;
75409
+ const heldPastEof = video.mediaStart >= playableDuration && canHoldFinalFramePastEof(video);
75410
+ if (video.mediaStart >= playableDuration && !heldPastEof) {
75377
75411
  throw new VideoSourceExtractionError(
75378
75412
  "media_start_out_of_range",
75379
75413
  false,
@@ -75382,9 +75416,13 @@ function resolveVideoExtractionWindow(video, metadata, timelineEnd) {
75382
75416
  );
75383
75417
  }
75384
75418
  const playbackRate = normalizePlaybackRate(video.playbackRate ?? 1);
75385
- const requestedTimelineDuration = video.end - video.start;
75386
75419
  const resolvedDuration = Number.isFinite(requestedTimelineDuration) && requestedTimelineDuration > 0 ? requestedTimelineDuration : resolveSegmentDuration(requestedTimelineDuration, video.mediaStart, playableDuration) / playbackRate;
75387
- return resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, playableDuration);
75420
+ return resolveTimelineExtractionWindow(
75421
+ video,
75422
+ resolvedDuration,
75423
+ timelineEnd ?? (heldPastEof ? video.end : void 0),
75424
+ playableDuration
75425
+ );
75388
75426
  }
75389
75427
  function resolveVideoExtractionDuration(video, metadata, timelineEnd) {
75390
75428
  return resolveVideoExtractionWindow(video, metadata, timelineEnd).durationSeconds;
@@ -75700,7 +75738,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75700
75738
  const metadata = videoMetadata[i];
75701
75739
  if (!entry || !metadata) continue;
75702
75740
  const playableDuration = resolvePlayableVideoDuration(metadata);
75703
- if (entry.video.mediaStart >= playableDuration) {
75741
+ if (entry.video.mediaStart >= playableDuration && !canHoldFinalFramePastEof(entry.video)) {
75704
75742
  errors.push({
75705
75743
  videoId: entry.video.id,
75706
75744
  kind: "media_start_out_of_range",
@@ -76267,6 +76305,7 @@ var init_videoFrameExtractor = __esm({
76267
76305
 
76268
76306
  // ../engine/src/services/videoFrameInjector.ts
76269
76307
  import { promises as fs } from "fs";
76308
+ import { dirname as dirname7 } from "path";
76270
76309
  function createFrameSourceCache(entryLimit, bytesLimit, frameSrcResolver) {
76271
76310
  const cache = /* @__PURE__ */ new Map();
76272
76311
  const inFlight = /* @__PURE__ */ new Map();
@@ -76346,6 +76385,15 @@ function createVideoFrameInjector(frameLookup, config) {
76346
76385
  const bytesLimit = bytesLimitMb * 1024 * 1024;
76347
76386
  const frameCache = createFrameSourceCache(entryLimit, bytesLimit, config?.frameSrcResolver);
76348
76387
  const lastInjectedFrameByVideo = /* @__PURE__ */ new Map();
76388
+ const lastCacheTouchByDir = /* @__PURE__ */ new Map();
76389
+ function renewCacheLease(framePath) {
76390
+ const cacheDir = dirname7(framePath);
76391
+ const now = Date.now();
76392
+ const lastTouch = lastCacheTouchByDir.get(cacheDir);
76393
+ if (lastTouch !== void 0 && now - lastTouch < CACHE_TOUCH_THROTTLE_MS) return;
76394
+ touchCacheDir(cacheDir);
76395
+ lastCacheTouchByDir.set(cacheDir, now);
76396
+ }
76349
76397
  return async (page, time) => {
76350
76398
  const activePayloads = frameLookup.getActiveFramePayloads(time);
76351
76399
  const updates = [];
@@ -76354,6 +76402,7 @@ function createVideoFrameInjector(frameLookup, config) {
76354
76402
  const pendingReads = [];
76355
76403
  for (const [videoId, payload] of activePayloads) {
76356
76404
  activeIds.add(videoId);
76405
+ renewCacheLease(payload.framePath);
76357
76406
  const lastFrameIndex = lastInjectedFrameByVideo.get(videoId);
76358
76407
  if (lastFrameIndex === payload.frameIndex) continue;
76359
76408
  pendingReads.push(
@@ -76679,12 +76728,15 @@ async function queryElementStacking(page, nativeHdrIds) {
76679
76728
  RENDER_FRAME_ID_SUFFIX
76680
76729
  );
76681
76730
  }
76731
+ var CACHE_TOUCH_THROTTLE_MS;
76682
76732
  var init_videoFrameInjector = __esm({
76683
76733
  "../engine/src/services/videoFrameInjector.ts"() {
76684
76734
  "use strict";
76735
+ init_extractionCache();
76685
76736
  init_screenshotService();
76686
76737
  init_config();
76687
76738
  init_dist2();
76739
+ CACHE_TOUCH_THROTTLE_MS = 5 * 60 * 1e3;
76688
76740
  }
76689
76741
  });
76690
76742
 
@@ -76839,7 +76891,7 @@ var init_wavChunks = __esm({
76839
76891
 
76840
76892
  // ../engine/src/services/audioVolumeEnvelope.ts
76841
76893
  import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync3, renameSync as renameSync2, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "fs";
76842
- import { dirname as dirname7, join as join12 } from "path";
76894
+ import { dirname as dirname8, join as join12 } from "path";
76843
76895
  function readFmtChunk(buffer, body) {
76844
76896
  const format = buffer.readUInt16LE(body);
76845
76897
  const bits = buffer.readUInt16LE(body + 14);
@@ -76911,7 +76963,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
76911
76963
  const layout2 = parseWavLayout(buffer);
76912
76964
  if (!layout2) return false;
76913
76965
  scaleSamples(buffer, layout2, gainAt);
76914
- stagingDir = mkdtempSync3(join12(dirname7(wavPath), ".hf-volume-"));
76966
+ stagingDir = mkdtempSync3(join12(dirname8(wavPath), ".hf-volume-"));
76915
76967
  const tempPath = join12(stagingDir, "audio.wav");
76916
76968
  writeFileSync4(tempPath, buffer, { flag: "wx" });
76917
76969
  renameSync2(tempPath, wavPath);
@@ -78384,7 +78436,7 @@ var init_audioFxRender = __esm({
78384
78436
 
78385
78437
  // ../engine/src/services/audioMixer.ts
78386
78438
  import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync5, openSync as openSync2, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
78387
- import { join as join14, dirname as dirname8 } from "path";
78439
+ import { join as join14, dirname as dirname9 } from "path";
78388
78440
  function memberGroupKey(el) {
78389
78441
  return el.getAttribute(AUDIO_GROUP_RENDER_ID_ATTR) ?? el.getAttribute(HF_AUDIO_GROUP_ATTR);
78390
78442
  }
@@ -78687,7 +78739,7 @@ function parseAudioElements(html) {
78687
78739
  }
78688
78740
  async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
78689
78741
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78690
- const outputDir = dirname8(outputPath);
78742
+ const outputDir = dirname9(outputPath);
78691
78743
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78692
78744
  const playbackRate = normalizePlaybackRate(options?.playbackRate ?? 1);
78693
78745
  const args = [];
@@ -78731,7 +78783,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
78731
78783
  }
78732
78784
  async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, playbackRate = 1, signal, config) {
78733
78785
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78734
- const outputDir = dirname8(outputPath);
78786
+ const outputDir = dirname9(outputPath);
78735
78787
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78736
78788
  const normalizedPlaybackRate = normalizePlaybackRate(playbackRate);
78737
78789
  const outputArgs = await preparedAudioOutputArgs(srcPath, normalizedPlaybackRate);
@@ -78778,7 +78830,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, play
78778
78830
  }
78779
78831
  async function generateSilence(outputPath, duration, signal, config) {
78780
78832
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78781
- const outputDir = dirname8(outputPath);
78833
+ const outputDir = dirname9(outputPath);
78782
78834
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78783
78835
  const args = [
78784
78836
  "-f",
@@ -78832,7 +78884,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
78832
78884
  failures: result2.failure ? [result2.failure] : void 0
78833
78885
  };
78834
78886
  }
78835
- const outputDir = dirname8(outputPath);
78887
+ const outputDir = dirname9(outputPath);
78836
78888
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78837
78889
  const buildFilterComplex = (ignoreAutomation) => {
78838
78890
  const filterParts = [];
@@ -78940,7 +78992,7 @@ function groupNormalizeOptionUnsupported(stderr) {
78940
78992
  }
78941
78993
  async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal, config) {
78942
78994
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78943
- const outputDir = dirname8(outputPath);
78995
+ const outputDir = dirname9(outputPath);
78944
78996
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78945
78997
  const buildInputFilters = (ignoreKeyframes) => memberTracks.map((track, i) => {
78946
78998
  const delayMs = Math.round(track.start * 1e3);
@@ -85243,7 +85295,7 @@ import {
85243
85295
  writeFileSync as writeFileSync8
85244
85296
  } from "fs";
85245
85297
  import { homedir as homedir4, tmpdir as tmpdir4 } from "os";
85246
- import { dirname as dirname12, join as join25 } from "path";
85298
+ import { dirname as dirname13, join as join25 } from "path";
85247
85299
  async function compressToWoff2(input) {
85248
85300
  return Buffer.from(await compress(input));
85249
85301
  }
@@ -85270,8 +85322,8 @@ function readCachedCompression(path) {
85270
85322
  function cacheCompression(path, compressed) {
85271
85323
  let tempDir;
85272
85324
  try {
85273
- mkdirSync10(dirname12(path), { recursive: true });
85274
- tempDir = mkdtempSync7(join25(dirname12(path), ".compression-"));
85325
+ mkdirSync10(dirname13(path), { recursive: true });
85326
+ tempDir = mkdtempSync7(join25(dirname13(path), ".compression-"));
85275
85327
  const tmpPath = join25(tempDir, "font.woff2");
85276
85328
  writeFileSync8(tmpPath, compressed, { flag: "wx", mode: 420 });
85277
85329
  renameSync4(tmpPath, path);
@@ -85338,7 +85390,7 @@ import {
85338
85390
  appendFileSync
85339
85391
  } from "fs";
85340
85392
  import { tmpdir as tmpdir7 } from "os";
85341
- import { join as join43, dirname as dirname18, resolve as resolve13 } from "path";
85393
+ import { join as join43, dirname as dirname19, resolve as resolve13 } from "path";
85342
85394
  import { totalmem as totalmem3 } from "os";
85343
85395
  import { randomUUID as randomUUID3 } from "crypto";
85344
85396
  import { fileURLToPath as fileURLToPath5 } from "url";
@@ -85366,9 +85418,9 @@ import { join as join19, extname as extname4, resolve as resolve7, sep as sep3 }
85366
85418
  // ../producer/src/services/hyperframeRuntimeLoader.ts
85367
85419
  import { createHash as createHash4 } from "crypto";
85368
85420
  import { existsSync as existsSync15, readFileSync as readFileSync6 } from "fs";
85369
- import { dirname as dirname9, resolve as resolve6 } from "path";
85421
+ import { dirname as dirname10, resolve as resolve6 } from "path";
85370
85422
  import { fileURLToPath as fileURLToPath2 } from "url";
85371
- var PRODUCER_DIR = dirname9(fileURLToPath2(import.meta.url));
85423
+ var PRODUCER_DIR = dirname10(fileURLToPath2(import.meta.url));
85372
85424
  var SIBLING_MANIFEST_PATH = resolve6(PRODUCER_DIR, "hyperframe.manifest.json");
85373
85425
  var MODULE_RELATIVE_MANIFEST_PATH = resolve6(
85374
85426
  PRODUCER_DIR,
@@ -85411,7 +85463,7 @@ function resolveVerifiedHyperframeRuntime() {
85411
85463
  `[HyperframeRuntimeLoader] Invalid manifest at ${manifestPath}; missing iife artifact or sha256.`
85412
85464
  );
85413
85465
  }
85414
- const runtimePath = resolve6(dirname9(manifestPath), runtimeFileName);
85466
+ const runtimePath = resolve6(dirname10(manifestPath), runtimeFileName);
85415
85467
  if (!existsSync15(runtimePath)) {
85416
85468
  throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
85417
85469
  }
@@ -86085,7 +86137,7 @@ import {
86085
86137
  symlinkSync,
86086
86138
  writeFileSync as writeFileSync7
86087
86139
  } from "fs";
86088
- import { basename as basename4, dirname as dirname10, isAbsolute as isAbsolute2, join as join21, relative, resolve as resolve8 } from "path";
86140
+ import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute2, join as join21, relative, resolve as resolve8 } from "path";
86089
86141
 
86090
86142
  // ../producer/src/utils/paths.ts
86091
86143
  import {
@@ -86170,7 +86222,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
86170
86222
  writeFileSync7(join21(compileDir, "index.html"), compiled.html, "utf-8");
86171
86223
  for (const [srcPath, html] of compiled.subCompositions) {
86172
86224
  const outPath = join21(compileDir, srcPath);
86173
- mkdirSync9(dirname10(outPath), { recursive: true });
86225
+ mkdirSync9(dirname11(outPath), { recursive: true });
86174
86226
  writeFileSync7(outPath, html, "utf-8");
86175
86227
  }
86176
86228
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
@@ -86179,7 +86231,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
86179
86231
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
86180
86232
  continue;
86181
86233
  }
86182
- mkdirSync9(dirname10(outPath), { recursive: true });
86234
+ mkdirSync9(dirname11(outPath), { recursive: true });
86183
86235
  copyFileSync3(absolutePath, outPath);
86184
86236
  }
86185
86237
  if (includeSummary) {
@@ -86233,7 +86285,7 @@ function updateJobStatus(job, status, stage, progress, onProgress) {
86233
86285
  var materializePathModule = {
86234
86286
  resolve: resolve8,
86235
86287
  join: join21,
86236
- dirname: dirname10,
86288
+ dirname: dirname11,
86237
86289
  basename: basename4,
86238
86290
  relative,
86239
86291
  isAbsolute: isAbsolute2
@@ -86535,7 +86587,7 @@ import {
86535
86587
  renameSync as renameSync3,
86536
86588
  rmSync as rmSync8
86537
86589
  } from "fs";
86538
- import { basename as basename5, dirname as dirname11, extname as extname5, join as join22, resolve as resolve9 } from "path";
86590
+ import { basename as basename5, dirname as dirname12, extname as extname5, join as join22, resolve as resolve9 } from "path";
86539
86591
 
86540
86592
  // ../producer/src/utils/ffprobe.ts
86541
86593
  init_src();
@@ -86554,7 +86606,7 @@ async function defaultArtifactDurationProbe(path) {
86554
86606
  };
86555
86607
  }
86556
86608
  function createSiblingTransactionDirectory(destination) {
86557
- const parent = dirname11(destination);
86609
+ const parent = dirname12(destination);
86558
86610
  const extension = extname5(destination);
86559
86611
  const stem = extension ? basename5(destination, extension) : basename5(destination);
86560
86612
  return mkdtempSync6(join22(parent, `.${stem}.hf-transaction-`));
@@ -87900,7 +87952,7 @@ init_subCompositionValidity();
87900
87952
  init_assetResolution();
87901
87953
  import { createHash as createHash9 } from "crypto";
87902
87954
  import { createReadStream as createReadStream4, existsSync as existsSync24, mkdirSync as mkdirSync13, readFileSync as readFileSync10 } from "fs";
87903
- import { join as join28, dirname as dirname14, resolve as resolve12, basename as basename6, relative as relative2 } from "path";
87955
+ import { join as join28, dirname as dirname15, resolve as resolve12, basename as basename6, relative as relative2 } from "path";
87904
87956
 
87905
87957
  // ../producer/src/services/renderMediaCollector.ts
87906
87958
  init_esm10();
@@ -89249,7 +89301,7 @@ import {
89249
89301
  rmSync as rmSync10,
89250
89302
  statSync as statSync8
89251
89303
  } from "fs";
89252
- import { dirname as dirname13, isAbsolute as isAbsolute3, join as join27, resolve as resolve11 } from "path";
89304
+ import { dirname as dirname14, isAbsolute as isAbsolute3, join as join27, resolve as resolve11 } from "path";
89253
89305
  var PREPARED_GIF_SUBDIR = "_animated_gif";
89254
89306
  var CACHE_SCHEMA = "hfgif-v1";
89255
89307
  function splitUrlSuffix(src) {
@@ -89402,11 +89454,11 @@ async function runAnimatedGifTranscode(request) {
89402
89454
  throw result.error ?? new Error(`Animated GIF transcode failed (${result.exitCode}): ${result.stderr.slice(-500)}`);
89403
89455
  }
89404
89456
  async function ensurePreparedWebm(input) {
89405
- if (!existsSync22(dirname13(input.cachePath))) {
89406
- mkdirSync12(dirname13(input.cachePath), { recursive: true });
89457
+ if (!existsSync22(dirname14(input.cachePath))) {
89458
+ mkdirSync12(dirname14(input.cachePath), { recursive: true });
89407
89459
  }
89408
- if (!existsSync22(dirname13(input.outputPath))) {
89409
- mkdirSync12(dirname13(input.outputPath), { recursive: true });
89460
+ if (!existsSync22(dirname14(input.outputPath))) {
89461
+ mkdirSync12(dirname14(input.outputPath), { recursive: true });
89410
89462
  }
89411
89463
  if (!isUsableFile(input.cachePath)) {
89412
89464
  const tmpPath = `${input.cachePath}.tmp-${process.pid}-${Date.now()}`;
@@ -90329,7 +90381,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, visited = /*
90329
90381
  workItems.map(async (item) => {
90330
90382
  const { html: compiledSub } = await compileHtmlFile(
90331
90383
  item.rawSubHtml,
90332
- dirname14(item.filePath),
90384
+ dirname15(item.filePath),
90333
90385
  downloadDir
90334
90386
  );
90335
90387
  const nested = await parseSubCompositions(
@@ -94762,7 +94814,7 @@ import { join as join38 } from "path";
94762
94814
  // ../producer/src/services/shaderTransitionWorkerPool.ts
94763
94815
  import { Worker as Worker2 } from "worker_threads";
94764
94816
  import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL2 } from "url";
94765
- import { dirname as dirname15, join as join37 } from "path";
94817
+ import { dirname as dirname16, join as join37 } from "path";
94766
94818
  import { createRequire as createRequire2 } from "module";
94767
94819
  import { existsSync as existsSync26 } from "fs";
94768
94820
  import { cpus as cpus3 } from "os";
@@ -94775,7 +94827,7 @@ function resolveWorkerEntry(explicit) {
94775
94827
  const isTs = override.endsWith(".ts");
94776
94828
  return { path: override, isTs };
94777
94829
  }
94778
- const moduleDir = dirname15(fileURLToPath4(import.meta.url));
94830
+ const moduleDir = dirname16(fileURLToPath4(import.meta.url));
94779
94831
  const jsPath = join37(moduleDir, "shaderTransitionWorker.js");
94780
94832
  if (existsSync26(jsPath)) return { path: jsPath, isTs: false };
94781
94833
  const tsPath = join37(moduleDir, "shaderTransitionWorker.ts");
@@ -95486,7 +95538,7 @@ async function runCaptureHdrStage(input) {
95486
95538
  // ../producer/src/services/render/stages/encodeStage.ts
95487
95539
  init_src();
95488
95540
  import { copyFileSync as copyFileSync5, existsSync as existsSync28, mkdirSync as mkdirSync16, readdirSync as readdirSync10, rmSync as rmSync12, statSync as statSync9 } from "fs";
95489
- import { dirname as dirname16, join as join41 } from "path";
95541
+ import { dirname as dirname17, join as join41 } from "path";
95490
95542
 
95491
95543
  // ../producer/src/services/render/stages/gifEncodeArgs.ts
95492
95544
  import { join as join40 } from "path";
@@ -95657,7 +95709,7 @@ async function runEncodeStage(input) {
95657
95709
  const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
95658
95710
  fps: job.config.fps,
95659
95711
  loop,
95660
- palettePath: join41(dirname16(videoOnlyPath), "gif-palette.png"),
95712
+ palettePath: join41(dirname17(videoOnlyPath), "gif-palette.png"),
95661
95713
  preserveAlpha: needsAlpha,
95662
95714
  signal: abortSignal,
95663
95715
  timeout: engineCfg.ffmpegEncodeTimeout
@@ -95724,7 +95776,7 @@ init_src();
95724
95776
  init_dist2();
95725
95777
  import { spawn as spawn5 } from "child_process";
95726
95778
  import { mkdtempSync as mkdtempSync10, renameSync as renameSync6, rmSync as rmSync13 } from "fs";
95727
- import { dirname as dirname17, join as join42 } from "path";
95779
+ import { dirname as dirname18, join as join42 } from "path";
95728
95780
  var AUDIO_DURATION_TOLERANCE_SECONDS = 1e-3;
95729
95781
  var AAC_DELIVERY_TRUE_PEAK_DBFS = -1;
95730
95782
  var AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB = 0.5;
@@ -95925,7 +95977,7 @@ async function padOrTrimAudioToVideoFrameCount(input) {
95925
95977
  async function enforceAacTruePeak(input) {
95926
95978
  let scratchDir;
95927
95979
  try {
95928
- scratchDir = mkdtempSync10(join42(dirname17(input.audioPath), ".true-peak-"));
95980
+ scratchDir = mkdtempSync10(join42(dirname18(input.audioPath), ".true-peak-"));
95929
95981
  const correctedPath = join42(scratchDir, "audio.m4a");
95930
95982
  const correctionTargetDbfs = AAC_DELIVERY_TRUE_PEAK_DBFS - AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB;
95931
95983
  const measurements = [];
@@ -96380,7 +96432,7 @@ function getNextRetryWorkerCount(currentWorkers) {
96380
96432
  }
96381
96433
  function resolveRenderWorkDirPrefix(outputPath, jobId, platform3 = process.platform, systemTempDir = tmpdir7()) {
96382
96434
  if (platform3 === "win32") return join43(systemTempDir, "hf-render-");
96383
- return join43(dirname18(outputPath), `work-${jobId}-`);
96435
+ return join43(dirname19(outputPath), `work-${jobId}-`);
96384
96436
  }
96385
96437
  var MAX_TRANSIENT_CAPTURE_RETRIES = 1;
96386
96438
  function captureAttemptMadeProgress(attemptTargetFrameCount, remainingFrameCount) {
@@ -96740,6 +96792,7 @@ function shouldRetryViaPinnedFallback(args) {
96740
96792
  if (args.isCancellation || args.isEncoderInterrupted) return false;
96741
96793
  if (args.isVerifyError || args.isDeCaptureError) return true;
96742
96794
  if (args.isDeRendererStall === true || args.isSequentialCaptureStall === true) return true;
96795
+ if (args.isTransientCaptureError === true) return true;
96743
96796
  return args.deWorkerInversion === "inverted" || args.deParallelRouter === "routed";
96744
96797
  }
96745
96798
  function isDeRendererStallError(err) {
@@ -96802,10 +96855,10 @@ function deVerifyFallbackTelemetry(err) {
96802
96855
  };
96803
96856
  }
96804
96857
  async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal) {
96805
- const moduleDir = dirname18(fileURLToPath5(import.meta.url));
96858
+ const moduleDir = dirname19(fileURLToPath5(import.meta.url));
96806
96859
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve13(process.env.PRODUCER_RENDERS_DIR, "..") : resolve13(moduleDir, "../..");
96807
96860
  const debugDir = join43(producerRoot, ".debug");
96808
- const outputDir = dirname18(outputPath);
96861
+ const outputDir = dirname19(outputPath);
96809
96862
  if (!existsSync29(outputDir)) mkdirSync17(outputDir, { recursive: true });
96810
96863
  const workDir = job.config.debug ? join43(debugDir, job.id) : mkdtempSync11(resolveRenderWorkDirPrefix(outputPath, job.id));
96811
96864
  const pipelineStart = Date.now();
@@ -97853,7 +97906,8 @@ async function executeRenderPipeline(input) {
97853
97906
  deWorkerInversion,
97854
97907
  deParallelRouter,
97855
97908
  isDeRendererStall: isDeStall,
97856
- isSequentialCaptureStall: isSequentialStall
97909
+ isSequentialCaptureStall: isSequentialStall,
97910
+ isTransientCaptureError: isTransientBrowserError(err)
97857
97911
  }))
97858
97912
  throw err;
97859
97913
  const isMemoryExhaustion = !isVerifyError && isMemoryExhaustionError(err);
@@ -98533,7 +98587,7 @@ import {
98533
98587
  rmSync as rmSync15,
98534
98588
  createReadStream as createReadStream5
98535
98589
  } from "fs";
98536
- import { resolve as resolve15, dirname as dirname20, join as join46 } from "path";
98590
+ import { resolve as resolve15, dirname as dirname21, join as join46 } from "path";
98537
98591
  import { tmpdir as tmpdir8 } from "os";
98538
98592
  import { parseArgs } from "util";
98539
98593
  import crypto from "crypto";
@@ -98662,7 +98716,7 @@ async function runHyperframeLint(prepared) {
98662
98716
  // ../producer/src/services/healthWorker.ts
98663
98717
  import { Worker as Worker3 } from "worker_threads";
98664
98718
  import { fileURLToPath as fileURLToPath6 } from "url";
98665
- import { dirname as dirname19, join as join45 } from "path";
98719
+ import { dirname as dirname20, join as join45 } from "path";
98666
98720
  import { existsSync as existsSync31 } from "fs";
98667
98721
  var DEFAULT_HEALTH_PORT = 9848;
98668
98722
  async function startHealthWorker(options = {}) {
@@ -98737,7 +98791,7 @@ function defaultLogger2() {
98737
98791
  };
98738
98792
  }
98739
98793
  function resolveWorkerEntry2() {
98740
- const here = dirname19(fileURLToPath6(import.meta.url));
98794
+ const here = dirname20(fileURLToPath6(import.meta.url));
98741
98795
  const candidates = [join45(here, "healthWorkerThread.js"), join45(here, "healthWorkerThread.ts")];
98742
98796
  for (const candidate of candidates) {
98743
98797
  if (existsSync31(candidate)) return candidate;
@@ -98875,7 +98929,7 @@ function buildRenderJobConfig(input, outputPath, log) {
98875
98929
  function resolvePreparedRenderOutput(prepared, rendersDir, log) {
98876
98930
  const { input, cleanupProjectDir } = prepared;
98877
98931
  const absoluteOutputPath = resolveOutputPath(input.projectDir, input.outputPath, rendersDir, log);
98878
- const outputDir = dirname20(absoluteOutputPath);
98932
+ const outputDir = dirname21(absoluteOutputPath);
98879
98933
  if (!existsSync32(outputDir)) mkdirSync18(outputDir, { recursive: true });
98880
98934
  return { input, cleanupProjectDir, absoluteOutputPath };
98881
98935
  }
@@ -99441,7 +99495,7 @@ var FIELD_DELIMITER = Buffer.from([0]);
99441
99495
  // ../producer/src/services/distributed/shared.ts
99442
99496
  init_src();
99443
99497
  import { execFile as execFileCallback } from "child_process";
99444
- import { dirname as dirname21, join as join48 } from "path";
99498
+ import { dirname as dirname22, join as join48 } from "path";
99445
99499
  import { existsSync as existsSync34, readFileSync as readFileSync15 } from "fs";
99446
99500
  import { fileURLToPath as fileURLToPath7 } from "url";
99447
99501
  import { promisify as promisify4 } from "util";
@@ -99488,7 +99542,7 @@ import {
99488
99542
  } from "fs";
99489
99543
  import { createHash as createHash12 } from "crypto";
99490
99544
  import { tmpdir as tmpdir9 } from "os";
99491
- import { dirname as dirname23, isAbsolute as isAbsolute5, join as join53, relative as relative7, resolve as resolve17, sep as sep6 } from "path";
99545
+ import { dirname as dirname24, isAbsolute as isAbsolute5, join as join53, relative as relative7, resolve as resolve17, sep as sep6 } from "path";
99492
99546
 
99493
99547
  // ../producer/src/services/distributed/planV2Publisher.ts
99494
99548
  import {
@@ -99502,7 +99556,7 @@ import {
99502
99556
  statSync as statSync13,
99503
99557
  writeFileSync as writeFileSync14
99504
99558
  } from "fs";
99505
- import { dirname as dirname22, join as join52 } from "path";
99559
+ import { dirname as dirname23, join as join52 } from "path";
99506
99560
 
99507
99561
  // ../producer/src/services/distributed/planV2Layout.ts
99508
99562
  import { join as join51 } from "path";
@@ -99526,7 +99580,7 @@ import {
99526
99580
  statSync as statSync15,
99527
99581
  writeFileSync as writeFileSync16
99528
99582
  } from "fs";
99529
- import { dirname as dirname24, join as join54 } from "path";
99583
+ import { dirname as dirname25, join as join54 } from "path";
99530
99584
 
99531
99585
  // ../producer/src/services/distributed/renderChunk.ts
99532
99586
  init_src();
@@ -99579,8 +99633,8 @@ async function runFontLocalize(io, localize) {
99579
99633
  }
99580
99634
 
99581
99635
  // src/version.ts
99582
- var VERSION = true ? "0.8.40" : "0.0.0-dev";
99583
- var PRODUCER_VERSION = true ? "0.8.40" : "0.0.0-dev";
99636
+ var VERSION = true ? "0.8.41" : "0.0.0-dev";
99637
+ var PRODUCER_VERSION = true ? "0.8.41" : "0.0.0-dev";
99584
99638
 
99585
99639
  // src/fontLocalizeCli.ts
99586
99640
  async function readStdin() {