@hyperframes/producer 0.9.25 → 0.9.27

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.
@@ -5,12 +5,12 @@ import {
5
5
  existsSync as existsSync24,
6
6
  mkdirSync as mkdirSync13,
7
7
  statSync as statSync11,
8
- mkdtempSync as mkdtempSync4,
8
+ mkdtempSync,
9
9
  writeFileSync as writeFileSync8,
10
10
  rmSync as rmSync13,
11
11
  createReadStream as createReadStream3
12
12
  } from "node:fs";
13
- import { resolve as resolve10, dirname as dirname15, join as join35 } from "node:path";
13
+ import { resolve as resolve10, dirname as dirname15, join as join34 } from "node:path";
14
14
  import { tmpdir as tmpdir3 } from "node:os";
15
15
  import { parseArgs } from "node:util";
16
16
  import crypto from "node:crypto";
@@ -84,7 +84,7 @@ import {
84
84
  referenceBackgroundResult,
85
85
  createReferenceBackgroundRecorder
86
86
  } from "@hyperframes/engine";
87
- import { join as join31, dirname as dirname13, resolve as resolve8 } from "path";
87
+ import { join as join30, dirname as dirname13, resolve as resolve8 } from "path";
88
88
  import { totalmem as totalmem2 } from "node:os";
89
89
  import { randomUUID } from "crypto";
90
90
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -1571,7 +1571,7 @@ var RenderExecutionContext = class {
1571
1571
 
1572
1572
  // src/services/render/artifactTransaction.ts
1573
1573
  import { closeSync as closeSync2, existsSync as existsSync6, fstatSync as fstatSync2, openSync as openSync2, readSync, readdirSync as readdirSync2, rmSync as rmSync3 } from "node:fs";
1574
- import { basename as basename3, dirname as dirname4, extname as extname2, join as join5, resolve as resolve4 } from "node:path";
1574
+ import { basename as basename4, dirname as dirname4, extname as extname2, join as join5, resolve as resolve4 } from "node:path";
1575
1575
  import { HLS_MASTER_PLAYLIST, HLS_VIDEO_PLAYLIST, renameWithRetry } from "@hyperframes/engine";
1576
1576
 
1577
1577
  // src/utils/ffprobe.ts
@@ -1585,7 +1585,6 @@ import {
1585
1585
  import {
1586
1586
  existsSync as existsSync5,
1587
1587
  lstatSync,
1588
- mkdtempSync,
1589
1588
  readFileSync as readFileSync2,
1590
1589
  readdirSync,
1591
1590
  readlinkSync,
@@ -1593,8 +1592,9 @@ import {
1593
1592
  writeFileSync as writeFileSync2
1594
1593
  } from "node:fs";
1595
1594
  import { hostname, uptime } from "node:os";
1596
- import { dirname as dirname3, join as join4 } from "node:path";
1595
+ import { basename as basename3, dirname as dirname3, join as join4 } from "node:path";
1597
1596
  import { RENDER_TEMP_DIR } from "@hyperframes/core/project-folders";
1597
+ import { createStagingDir } from "@hyperframes/core/atomic-file";
1598
1598
  var OWNER_FILE = "owner.json";
1599
1599
  var TRANSACTION_BACKUP = "backup";
1600
1600
  function pidScope() {
@@ -1613,7 +1613,7 @@ function pidScope() {
1613
1613
  };
1614
1614
  }
1615
1615
  function createOwnedRenderDir(prefix) {
1616
- const dir = mkdtempSync(prefix);
1616
+ const dir = createStagingDir(dirname3(prefix), basename3(prefix));
1617
1617
  const owner = { pid: process.pid, ...pidScope() };
1618
1618
  writeFileSync2(join4(dir, OWNER_FILE), JSON.stringify(owner));
1619
1619
  return dir;
@@ -1723,7 +1723,7 @@ function buildArtifactExpectation(input) {
1723
1723
  function createSiblingTransactionDirectory(destination) {
1724
1724
  const parent = dirname4(destination);
1725
1725
  const extension = extname2(destination);
1726
- const stem = extension ? basename3(destination, extension) : basename3(destination);
1726
+ const stem = extension ? basename4(destination, extension) : basename4(destination);
1727
1727
  return createOwnedRenderDir(join5(parent, `.${stem}.hf-transaction-`));
1728
1728
  }
1729
1729
  function assertReadableNonEmptyFile(path) {
@@ -1799,7 +1799,7 @@ var ArtifactTransaction = class {
1799
1799
  this.logger = logger;
1800
1800
  this.destinationPath = resolve4(destinationPath);
1801
1801
  this.transactionDirectory = createSiblingTransactionDirectory(this.destinationPath);
1802
- this.stagingPath = join5(this.transactionDirectory, basename3(this.destinationPath));
1802
+ this.stagingPath = join5(this.transactionDirectory, basename4(this.destinationPath));
1803
1803
  this.backupPath = join5(this.transactionDirectory, TRANSACTION_BACKUP);
1804
1804
  this.durationProbe = durationProbe;
1805
1805
  }
@@ -1855,7 +1855,7 @@ var ArtifactTransaction = class {
1855
1855
  }
1856
1856
  if (expected.expectedFrames === void 0) return;
1857
1857
  const frameCount = files.filter(
1858
- (file) => dirname4(file) === this.stagingPath && /^frame_\d+\.png$/.test(basename3(file))
1858
+ (file) => dirname4(file) === this.stagingPath && /^frame_\d+\.png$/.test(basename4(file))
1859
1859
  ).length;
1860
1860
  if (frameCount === 0) {
1861
1861
  throw new Error(
@@ -2094,7 +2094,7 @@ function replanAfterFailure(plan, failure) {
2094
2094
 
2095
2095
  // src/services/render/stages/captureSegmentedStage.ts
2096
2096
  import { existsSync as existsSync7, mkdirSync as mkdirSync3, rmSync as rmSync6, statSync as statSync3 } from "node:fs";
2097
- import { join as join10 } from "node:path";
2097
+ import { join as join9 } from "node:path";
2098
2098
  import {
2099
2099
  captureFrameToBuffer as captureFrameToBuffer2,
2100
2100
  closeCaptureSession as closeCaptureSession2,
@@ -2987,8 +2987,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
2987
2987
  }
2988
2988
 
2989
2989
  // src/services/render/stages/captureHdrResources.ts
2990
- import { mkdirSync as mkdirSync2, mkdtempSync as mkdtempSync2, readFileSync as readFileSync3, rmSync as rmSync5, statSync as statSync2, statfsSync } from "node:fs";
2991
- import { join as join8 } from "node:path";
2990
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync as rmSync5, statSync as statSync2, statfsSync } from "node:fs";
2992
2991
  import {
2993
2992
  decodePngToRgb48le,
2994
2993
  extractMediaMetadata as extractMediaMetadata2,
@@ -3088,6 +3087,7 @@ function createHdrFrameWindows(opts) {
3088
3087
  }
3089
3088
 
3090
3089
  // src/services/render/stages/captureHdrResources.ts
3090
+ import { createStagingDir as createStagingDir2 } from "@hyperframes/core/atomic-file";
3091
3091
  function tempDirSafePrefix(id) {
3092
3092
  const safe = id.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 80);
3093
3093
  return safe || "video";
@@ -3345,7 +3345,7 @@ async function extractHdrVideoFrames(args) {
3345
3345
  if (!video || !planned) continue;
3346
3346
  const { window: window2, metadata } = planned;
3347
3347
  mkdirSync2(framesDir, { recursive: true });
3348
- const frameDir = mkdtempSync2(join8(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
3348
+ const frameDir = createStagingDir2(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`);
3349
3349
  createdFrameDirs.add(frameDir);
3350
3350
  const dims = prep.hdrExtractionDims.get(videoId) ?? { width, height };
3351
3351
  const frameSize = dims.width * dims.height * 6;
@@ -3800,7 +3800,7 @@ function isTargetLossError(error) {
3800
3800
  // src/services/render/stages/captureStreamingStage.ts
3801
3801
  import { mkdtemp, writeFile } from "node:fs/promises";
3802
3802
  import { tmpdir } from "node:os";
3803
- import { join as join9 } from "node:path";
3803
+ import { join as join8 } from "node:path";
3804
3804
  import {
3805
3805
  DrawElementVerificationError,
3806
3806
  captureFrameToBuffer,
@@ -4023,11 +4023,11 @@ async function verifyDrawElementSample(session, idx, buf, ctx) {
4023
4023
  return;
4024
4024
  }
4025
4025
  if (db < verifyMinDb) {
4026
- const dumpDir = await mkdtemp(join9(tmpdir(), "hf-de-verify-fail-")).catch(() => null);
4026
+ const dumpDir = await mkdtemp(join8(tmpdir(), "hf-de-verify-fail-")).catch(() => null);
4027
4027
  if (dumpDir) {
4028
4028
  await Promise.all([
4029
- writeFile(join9(dumpDir, `frame-${idx}-de.jpg`), buf),
4030
- writeFile(join9(dumpDir, `frame-${idx}-truth.jpg`), truth)
4029
+ writeFile(join8(dumpDir, `frame-${idx}-de.jpg`), buf),
4030
+ writeFile(join8(dumpDir, `frame-${idx}-truth.jpg`), truth)
4031
4031
  ]).catch(() => {
4032
4032
  });
4033
4033
  }
@@ -4598,7 +4598,7 @@ async function runCaptureStreamingStage(input) {
4598
4598
 
4599
4599
  // src/services/render/stages/captureSegmentedStage.ts
4600
4600
  function segmentOutputPath(segmentDir, index) {
4601
- return join10(segmentDir, `segment_${String(index).padStart(5, "0")}.mp4`);
4601
+ return join9(segmentDir, `segment_${String(index).padStart(5, "0")}.mp4`);
4602
4602
  }
4603
4603
  function segmentEncoderOptions(base, segment) {
4604
4604
  return {
@@ -4926,7 +4926,7 @@ async function runCaptureSegmentedStage(input) {
4926
4926
  const { log, dedupPerfs, assertNotAborted } = input;
4927
4927
  const deps = { ...DEFAULT_DEPS, ...input.deps };
4928
4928
  const segments = planSegments(input.totalFrames, input.segmentFrames);
4929
- const segmentDir = input.segmentDir ?? join10(input.workDir, "segments");
4929
+ const segmentDir = input.segmentDir ?? join9(input.workDir, "segments");
4930
4930
  mkdirSync3(segmentDir, { recursive: true });
4931
4931
  const skip = input.completedSegments ?? /* @__PURE__ */ new Set();
4932
4932
  const pending = segments.filter((s) => !skip.has(s.index));
@@ -5073,7 +5073,7 @@ function startRenderEtaGuard(options) {
5073
5073
  }
5074
5074
 
5075
5075
  // src/services/render/captureCost.ts
5076
- import { join as join11 } from "node:path";
5076
+ import { join as join10 } from "node:path";
5077
5077
  import { fpsToNumber as fpsToNumber4 } from "@hyperframes/core";
5078
5078
  import {
5079
5079
  calculateOptimalWorkers,
@@ -5319,7 +5319,7 @@ async function runCaptureCalibration(input) {
5319
5319
  });
5320
5320
  let calibration;
5321
5321
  try {
5322
- calibration = await runOneCalibration(join11(workDir, "capture-calibration"), calibrationCfg);
5322
+ calibration = await runOneCalibration(join10(workDir, "capture-calibration"), calibrationCfg);
5323
5323
  } catch (error) {
5324
5324
  const shouldFallback = !forceScreenshot && shouldFallbackToScreenshotAfterCalibrationError(error);
5325
5325
  if (!shouldFallback) {
@@ -5353,7 +5353,7 @@ async function runCaptureCalibration(input) {
5353
5353
  const screenshotCfg = createCaptureCalibrationConfig({ ...cfg, forceScreenshot: true });
5354
5354
  try {
5355
5355
  calibration = await runOneCalibration(
5356
- join11(workDir, "capture-calibration-screenshot"),
5356
+ join10(workDir, "capture-calibration-screenshot"),
5357
5357
  screenshotCfg
5358
5358
  );
5359
5359
  } catch (fallbackError) {
@@ -5418,7 +5418,7 @@ function checkPageNeverReady(input) {
5418
5418
 
5419
5419
  // src/services/render/deferredVideoFrames.ts
5420
5420
  import { mkdirSync as mkdirSync4, rmSync as rmSync7 } from "node:fs";
5421
- import { dirname as dirname5, join as join12 } from "node:path";
5421
+ import { dirname as dirname5, join as join11 } from "node:path";
5422
5422
  import {
5423
5423
  createFrameLookupTable,
5424
5424
  extractVideoFramesRange,
@@ -5462,7 +5462,7 @@ async function extractDeferredFrames(input) {
5462
5462
  const shown = shownDeferredFrameIndexes(input, input.frames, input.fps);
5463
5463
  return Promise.all(
5464
5464
  deferred.map(async (video) => {
5465
- const outputDir = join12(input.outputRoot, video.videoId);
5465
+ const outputDir = join11(input.outputRoot, video.videoId);
5466
5466
  const indexes = [...shown.get(video.videoId) ?? []].sort((a, b) => a - b);
5467
5467
  if (indexes.length === 0) {
5468
5468
  return { ...video, outputDir, framePaths: /* @__PURE__ */ new Map(), ownedByLookup: false };
@@ -5531,13 +5531,13 @@ async function extractAllDeferredFrames(extracted, input) {
5531
5531
 
5532
5532
  // src/services/render/segmentVideoFrames.ts
5533
5533
  import { mkdirSync as mkdirSync5, rmSync as rmSync8 } from "node:fs";
5534
- import { join as join13 } from "node:path";
5534
+ import { join as join12 } from "node:path";
5535
5535
  import {
5536
5536
  createFrameLookupTable as createFrameLookupTable2,
5537
5537
  createVideoFrameInjector
5538
5538
  } from "@hyperframes/engine";
5539
5539
  function segmentFramesDir(rootDir, index) {
5540
- return join13(rootDir, "segment-frames", `segment_${String(index).padStart(5, "0")}`);
5540
+ return join12(rootDir, "segment-frames", `segment_${String(index).padStart(5, "0")}`);
5541
5541
  }
5542
5542
  function createSegmentVideoFrames(input) {
5543
5543
  const extractFrames = input.extractFrames ?? extractDeferredFrames;
@@ -5567,7 +5567,7 @@ function createSegmentVideoFrames(input) {
5567
5567
  let onDemandCalls = 0;
5568
5568
  const onDemandHook = () => Object.assign(
5569
5569
  async (page, time, heldVideoTime) => {
5570
- const dir = join13(
5570
+ const dir = join12(
5571
5571
  input.rootDir,
5572
5572
  "segment-frames",
5573
5573
  `on-demand_${String(onDemandCalls++).padStart(5, "0")}`
@@ -5584,7 +5584,7 @@ function createSegmentVideoFrames(input) {
5584
5584
  );
5585
5585
  return {
5586
5586
  async forFrames(frames, name) {
5587
- const dir = join13(input.rootDir, "segment-frames", name);
5587
+ const dir = join12(input.rootDir, "segment-frames", name);
5588
5588
  const release = () => rmSync8(dir, { recursive: true, force: true });
5589
5589
  try {
5590
5590
  release();
@@ -5637,7 +5637,7 @@ function createSegmentVideoFrames(input) {
5637
5637
 
5638
5638
  // src/services/render/videoFrameWindow.ts
5639
5639
  import { readdirSync as readdirSync3, statSync as statSync4 } from "node:fs";
5640
- import { join as join14 } from "node:path";
5640
+ import { join as join13 } from "node:path";
5641
5641
  function shouldWindowVideoFrames(args) {
5642
5642
  return args.segmented && args.env.HF_VIDEO_FRAME_WINDOW?.trim().toLowerCase() === "true";
5643
5643
  }
@@ -5650,7 +5650,7 @@ function directoryBytes(path) {
5650
5650
  return 0;
5651
5651
  }
5652
5652
  for (const entry of entries) {
5653
- const child2 = join14(path, entry.name);
5653
+ const child2 = join13(path, entry.name);
5654
5654
  try {
5655
5655
  bytes += entry.isDirectory() ? directoryBytes(child2) : statSync4(child2).size;
5656
5656
  } catch {
@@ -5668,7 +5668,7 @@ function trackSegmentFramePeak(frames, rootDir, onPeak) {
5668
5668
  ...worker,
5669
5669
  async prepare(segment) {
5670
5670
  await worker.prepare(segment);
5671
- const held = directoryBytes(join14(rootDir, "segment-frames"));
5671
+ const held = directoryBytes(join13(rootDir, "segment-frames"));
5672
5672
  if (held > peak) {
5673
5673
  peak = held;
5674
5674
  onPeak(peak);
@@ -5682,7 +5682,7 @@ function trackSegmentFramePeak(frames, rootDir, onPeak) {
5682
5682
  // src/services/render/segmentManifest.ts
5683
5683
  import { createHash as createHash2 } from "node:crypto";
5684
5684
  import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync4, statSync as statSync5, writeFileSync as writeFileSync3 } from "node:fs";
5685
- import { join as join15 } from "node:path";
5685
+ import { join as join14 } from "node:path";
5686
5686
  import { renameWithRetry as renameWithRetry2 } from "@hyperframes/engine";
5687
5687
  var MANIFEST_FILENAME = "segments.json";
5688
5688
  function computeSegmentPlanHash(input) {
@@ -5710,7 +5710,7 @@ function computeSegmentPlanHash(input) {
5710
5710
  return createHash2("sha256").update(ordered.join(" ")).digest("hex").slice(0, 16);
5711
5711
  }
5712
5712
  function segmentDirFor(projectRendersDir, planHash) {
5713
- return join15(projectRendersDir, ".hf-segments", planHash);
5713
+ return join14(projectRendersDir, ".hf-segments", planHash);
5714
5714
  }
5715
5715
  function hasNumber(value, key) {
5716
5716
  return key in value && typeof Reflect.get(value, key) === "number";
@@ -5728,7 +5728,7 @@ function isManifest(value) {
5728
5728
  return Reflect.get(value, "version") === 1 && hasString(value, "planHash") && hasNumber(value, "totalFrames") && hasNumber(value, "segmentFrames") && Array.isArray(completed) && completed.every(isEntry);
5729
5729
  }
5730
5730
  function readSegmentManifest(segmentDir) {
5731
- const path = join15(segmentDir, MANIFEST_FILENAME);
5731
+ const path = join14(segmentDir, MANIFEST_FILENAME);
5732
5732
  if (!existsSync8(path)) return null;
5733
5733
  try {
5734
5734
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
@@ -5739,9 +5739,9 @@ function readSegmentManifest(segmentDir) {
5739
5739
  }
5740
5740
  function writeSegmentManifest(segmentDir, manifest) {
5741
5741
  mkdirSync6(segmentDir, { recursive: true });
5742
- const tmp = join15(segmentDir, `${MANIFEST_FILENAME}.${process.pid}.tmp`);
5742
+ const tmp = join14(segmentDir, `${MANIFEST_FILENAME}.${process.pid}.tmp`);
5743
5743
  writeFileSync3(tmp, JSON.stringify(manifest, null, 2), "utf-8");
5744
- renameWithRetry2(tmp, join15(segmentDir, MANIFEST_FILENAME));
5744
+ renameWithRetry2(tmp, join14(segmentDir, MANIFEST_FILENAME));
5745
5745
  }
5746
5746
  async function probeSegmentFrameCount(path, probe) {
5747
5747
  try {
@@ -6338,7 +6338,7 @@ function countAuthoredTimedClips(html) {
6338
6338
 
6339
6339
  // src/services/render/stages/compileStage.ts
6340
6340
  import { existsSync as existsSync12, writeFileSync as writeFileSync5 } from "node:fs";
6341
- import { join as join19 } from "node:path";
6341
+ import { join as join18 } from "node:path";
6342
6342
  import { suggestMatchingPreset } from "@hyperframes/core";
6343
6343
  import { extractStandaloneEntryFromIndex, isTemplateEntry } from "@hyperframes/core/compiler";
6344
6344
  import { readTextFile as readTextFile2 } from "@hyperframes/parsers/asset-resolution";
@@ -6347,7 +6347,7 @@ import { readTextFile as readTextFile2 } from "@hyperframes/parsers/asset-resolu
6347
6347
  import { decodedUrlPath as decodedUrlPath2 } from "@hyperframes/parsers/asset-paths";
6348
6348
  import { createHash as createHash6 } from "node:crypto";
6349
6349
  import { createReadStream as createReadStream2, existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync7 } from "fs";
6350
- import { join as join18, dirname as dirname8, resolve as resolve7, basename as basename4, relative as relative2, sep as sep2 } from "path";
6350
+ import { join as join17, dirname as dirname8, resolve as resolve7, basename as basename5, relative as relative2, sep as sep2 } from "path";
6351
6351
  import { parseHTML as parseHTML5 } from "linkedom";
6352
6352
  import {
6353
6353
  COMPOSITION_SOURCE_URL,
@@ -6594,7 +6594,7 @@ import {
6594
6594
  // src/services/animatedGifPrep.ts
6595
6595
  import { createHash as createHash4 } from "node:crypto";
6596
6596
  import { copyFileSync as copyFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync5, rmSync as rmSync9, statSync as statSync6 } from "node:fs";
6597
- import { dirname as dirname6, isAbsolute as isAbsolute2, join as join16, resolve as resolve5 } from "node:path";
6597
+ import { dirname as dirname6, isAbsolute as isAbsolute2, join as join15, resolve as resolve5 } from "node:path";
6598
6598
  import { parseHTML as parseHTML3 } from "linkedom";
6599
6599
  import { parseAnimatedGifMetadata } from "@hyperframes/core";
6600
6600
  import { DEFAULT_VP9_CPU_USED, runFfmpeg as runFfmpeg2, renameWithRetry as renameWithRetry3 } from "@hyperframes/engine";
@@ -6837,7 +6837,7 @@ function replaceImageWithVideo(input) {
6837
6837
  return video;
6838
6838
  }
6839
6839
  async function prepareAnimatedGifInputs(html, options) {
6840
- const outputDir = options.outputDir ?? join16(options.downloadDir, PREPARED_GIF_SUBDIR);
6840
+ const outputDir = options.outputDir ?? join15(options.downloadDir, PREPARED_GIF_SUBDIR);
6841
6841
  const outputSrcPrefix = normalizeRelPath(options.outputSrcPrefix ?? PREPARED_GIF_SUBDIR);
6842
6842
  const cacheDir = options.cacheDir ?? outputDir;
6843
6843
  const { document: document2 } = parseHTML3(html);
@@ -6864,8 +6864,8 @@ async function prepareAnimatedGifInputs(html, options) {
6864
6864
  );
6865
6865
  const hash = computePreparedGifHash(bytes, loopIterations, padSeconds);
6866
6866
  const filename = `${CACHE_SCHEMA}-${hash.slice(0, 24)}.webm`;
6867
- const cachePath = join16(cacheDir, filename);
6868
- const outputPath = join16(outputDir, filename);
6867
+ const cachePath = join15(cacheDir, filename);
6868
+ const outputPath = join15(outputDir, filename);
6869
6869
  const outputSrc = `${outputSrcPrefix}/${filename}`;
6870
6870
  await ensurePreparedWebm({
6871
6871
  sourcePath,
@@ -6910,7 +6910,7 @@ import {
6910
6910
  statSync as statSync7,
6911
6911
  writeFileSync as writeFileSync4
6912
6912
  } from "node:fs";
6913
- import { dirname as dirname7, join as join17, resolve as resolve6 } from "node:path";
6913
+ import { dirname as dirname7, join as join16, resolve as resolve6 } from "node:path";
6914
6914
  import { parseHTML as parseHTML4 } from "linkedom";
6915
6915
  import { renameWithRetry as renameWithRetry4, runFfmpeg as runFfmpeg3, runFfprobe } from "@hyperframes/engine";
6916
6916
 
@@ -7184,7 +7184,7 @@ async function ensurePreparedJpeg(source, cachePath, outputPath, options) {
7184
7184
  }
7185
7185
  }
7186
7186
  async function prepareHeifImageInputs(html, options) {
7187
- const outputDir = options.outputDir ?? join17(options.downloadDir, PREPARED_HEIF_SUBDIR);
7187
+ const outputDir = options.outputDir ?? join16(options.downloadDir, PREPARED_HEIF_SUBDIR);
7188
7188
  const outputSrcPrefix = normalizeRelPath(options.outputSrcPrefix ?? PREPARED_HEIF_SUBDIR);
7189
7189
  const cacheDir = options.cacheDir ?? outputDir;
7190
7190
  const preparedAssets = /* @__PURE__ */ new Map();
@@ -7205,7 +7205,7 @@ async function prepareHeifImageInputs(html, options) {
7205
7205
  await Promise.all(
7206
7206
  [...unique].map(
7207
7207
  ([filename, source]) => withMediaProbeSlot(
7208
- () => ensurePreparedJpeg(source, join17(cacheDir, filename), join17(outputDir, filename), options)
7208
+ () => ensurePreparedJpeg(source, join16(cacheDir, filename), join16(outputDir, filename), options)
7209
7209
  ).catch((error) => {
7210
7210
  if (!options.onFailure) throw error;
7211
7211
  failed.add(filename);
@@ -7217,8 +7217,8 @@ async function prepareHeifImageInputs(html, options) {
7217
7217
  if (failed.has(filename)) continue;
7218
7218
  const outputSrc = `${outputSrcPrefix}/${filename}`;
7219
7219
  img.setAttribute("src", outputSrc);
7220
- preparedAssets.set(outputSrc, join17(outputDir, filename));
7221
- preparedImages.push({ sourceSrc: src, outputSrc, outputPath: join17(outputDir, filename) });
7220
+ preparedAssets.set(outputSrc, join16(outputDir, filename));
7221
+ preparedImages.push({ sourceSrc: src, outputSrc, outputPath: join16(outputDir, filename) });
7222
7222
  }
7223
7223
  return { html: document2.toString(), preparedAssets, preparedImages };
7224
7224
  }
@@ -7554,7 +7554,7 @@ function detectShaderTransitionUsage(html) {
7554
7554
  async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, downloadDir, tagName, elementIdentity, log, urlByAbsentLocalPath, probes) {
7555
7555
  let filePath = src;
7556
7556
  if (isHttpUrl(src)) {
7557
- const remoteDir = join18(downloadDir, REMOTE_MEDIA_SUBDIR);
7557
+ const remoteDir = join17(downloadDir, REMOTE_MEDIA_SUBDIR);
7558
7558
  if (!existsSync11(remoteDir)) mkdirSync9(remoteDir, { recursive: true });
7559
7559
  try {
7560
7560
  filePath = await downloadToTemp(src, remoteDir, void 0, void 0, void 0, {
@@ -7565,7 +7565,7 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
7565
7565
  }
7566
7566
  } else {
7567
7567
  filePath = decodedUrlPath2(src);
7568
- if (!filePath.startsWith("/")) filePath = join18(baseDir, filePath);
7568
+ if (!filePath.startsWith("/")) filePath = join17(baseDir, filePath);
7569
7569
  filePath = urlByAbsentLocalPath?.get(filePath) ?? filePath;
7570
7570
  }
7571
7571
  if (!isHttpUrl(filePath) && !existsSync11(filePath)) {
@@ -8181,7 +8181,7 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
8181
8181
  const remoteMediaAssets = /* @__PURE__ */ new Map();
8182
8182
  const urlToRelPath = /* @__PURE__ */ new Map();
8183
8183
  for (const [url, absPath] of urlToLocal) {
8184
- const relPath = `${REMOTE_MEDIA_SUBDIR}/${basename4(absPath)}`;
8184
+ const relPath = `${REMOTE_MEDIA_SUBDIR}/${basename5(absPath)}`;
8185
8185
  remoteMediaAssets.set(relPath, absPath);
8186
8186
  urlToRelPath.set(url, relPath);
8187
8187
  }
@@ -8205,7 +8205,7 @@ async function localizeRemoteMediaSources(html, downloadDir) {
8205
8205
  return downloadAndRewriteUrls(
8206
8206
  urlSet,
8207
8207
  html,
8208
- join18(downloadDir, REMOTE_MEDIA_SUBDIR),
8208
+ join17(downloadDir, REMOTE_MEDIA_SUBDIR),
8209
8209
  "Remote media download failed",
8210
8210
  "Localized remote media source(s)"
8211
8211
  );
@@ -8220,7 +8220,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
8220
8220
  return downloadAndRewriteUrls(
8221
8221
  urlSet,
8222
8222
  html,
8223
- join18(downloadDir, REMOTE_MEDIA_SUBDIR),
8223
+ join17(downloadDir, REMOTE_MEDIA_SUBDIR),
8224
8224
  "Remote image download failed",
8225
8225
  "Localized remote image source(s)"
8226
8226
  );
@@ -8236,7 +8236,7 @@ async function localizeRemoteBackgroundImages(html, downloadDir) {
8236
8236
  return downloadAndRewriteUrls(
8237
8237
  urlSet,
8238
8238
  html,
8239
- join18(downloadDir, REMOTE_MEDIA_SUBDIR),
8239
+ join17(downloadDir, REMOTE_MEDIA_SUBDIR),
8240
8240
  "Remote background-image download failed",
8241
8241
  "Localized remote background-image(s)",
8242
8242
  // Quoted url('..')/url("..") are rewritten by downloadAndRewriteUrls' default
@@ -8388,7 +8388,7 @@ function localizeFontFaceUrls(html, downloadDir) {
8388
8388
  return downloadAndRewriteUrls(
8389
8389
  collectFontFaceUrls(html),
8390
8390
  html,
8391
- join18(downloadDir, REMOTE_MEDIA_SUBDIR),
8391
+ join17(downloadDir, REMOTE_MEDIA_SUBDIR),
8392
8392
  "Remote font download failed",
8393
8393
  "Localized remote font face(s)",
8394
8394
  (h, url, relPath) => h.replaceAll(`url(${url})`, `url("${relPath}")`)
@@ -9065,10 +9065,10 @@ function adaptAspectAgnosticResolution(requested, aspectAgnostic, width, height,
9065
9065
  }
9066
9066
  function resolveEntryHtmlPath(input) {
9067
9067
  const { projectDir, workDir, entryFile, log } = input;
9068
- const htmlPath = join19(projectDir, entryFile);
9068
+ const htmlPath = join18(projectDir, entryFile);
9069
9069
  const rawEntry = readTextFile2(htmlPath);
9070
9070
  if (entryFile === "index.html" || !isTemplateEntry(rawEntry)) return htmlPath;
9071
- const projectIndexPath = join19(projectDir, "index.html");
9071
+ const projectIndexPath = join18(projectDir, "index.html");
9072
9072
  if (!existsSync12(projectIndexPath)) {
9073
9073
  throw new Error(
9074
9074
  `Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
@@ -9084,7 +9084,7 @@ function resolveEntryHtmlPath(input) {
9084
9084
  `Entry file "${entryFile}" is not mounted from index.html via data-composition-src, so it cannot be rendered independently.`
9085
9085
  );
9086
9086
  }
9087
- const wrapperPath = join19(workDir, "standalone-entry.html");
9087
+ const wrapperPath = join18(workDir, "standalone-entry.html");
9088
9088
  writeFileSync5(wrapperPath, standaloneHtml, "utf-8");
9089
9089
  log.info("Extracted standalone entry from index.html host context", { entryFile });
9090
9090
  return wrapperPath;
@@ -9105,7 +9105,7 @@ async function runCompileStage(input) {
9105
9105
  } = input;
9106
9106
  const htmlPath = resolveEntryHtmlPath({ projectDir, workDir, entryFile, log });
9107
9107
  const compileStart = Date.now();
9108
- const compiled = await compileForRender(projectDir, htmlPath, join19(workDir, "downloads"), {
9108
+ const compiled = await compileForRender(projectDir, htmlPath, join18(workDir, "downloads"), {
9109
9109
  log,
9110
9110
  failClosedFontFetch: failClosedFontFetch === true,
9111
9111
  allowSystemFontCapture,
@@ -9113,7 +9113,7 @@ async function runCompileStage(input) {
9113
9113
  variables: input.variables,
9114
9114
  urlByAbsentLocalPath: input.urlByAbsentLocalPath,
9115
9115
  pageMotionBlur: input.pageMotionBlur,
9116
- animatedGifCacheDir: cfg.extractCacheDir ? join19(cfg.extractCacheDir, "animated-gif") : void 0,
9116
+ animatedGifCacheDir: cfg.extractCacheDir ? join18(cfg.extractCacheDir, "animated-gif") : void 0,
9117
9117
  ffmpegProcessTimeout: cfg.ffmpegProcessTimeout
9118
9118
  });
9119
9119
  assertNotAborted();
@@ -9170,7 +9170,7 @@ async function runCompileStage(input) {
9170
9170
  };
9171
9171
  await preflightCompositionAssetMediaTypes({
9172
9172
  projectDir,
9173
- compiledDir: join19(workDir, "compiled"),
9173
+ compiledDir: join18(workDir, "compiled"),
9174
9174
  composition,
9175
9175
  signal: abortSignal
9176
9176
  });
@@ -9216,7 +9216,7 @@ async function runCompileStage(input) {
9216
9216
 
9217
9217
  // src/services/render/stages/probeStage.ts
9218
9218
  import { createHash as createHash7 } from "node:crypto";
9219
- import { basename as basename5, join as join20 } from "node:path";
9219
+ import { basename as basename6, join as join19 } from "node:path";
9220
9220
  import { parseHTML as parseHTML6 } from "linkedom";
9221
9221
  import {
9222
9222
  closeCaptureSession as closeCaptureSession4,
@@ -9366,7 +9366,7 @@ function probeRequiresBrowser(args) {
9366
9366
  function reportedLengthSource(source) {
9367
9367
  if (!source) return null;
9368
9368
  if (source.from !== "media") return { from: source.from };
9369
- const name = basename5(source.src.split(/[?#]/, 1)[0] ?? "");
9369
+ const name = basename6(source.src.split(/[?#]/, 1)[0] ?? "");
9370
9370
  const srcHash = createHash7("sha256").update(name).digest("hex").slice(0, 12);
9371
9371
  return { from: "media", tag: source.tag, trimmed: source.trimmed, srcHash };
9372
9372
  }
@@ -9425,7 +9425,7 @@ async function runProbeStage(input) {
9425
9425
  });
9426
9426
  fileServer = await createFileServer({
9427
9427
  projectDir,
9428
- compiledDir: join20(workDir, "compiled"),
9428
+ compiledDir: join19(workDir, "compiled"),
9429
9429
  port: 0,
9430
9430
  preHeadScripts: [VIRTUAL_TIME_SHIM],
9431
9431
  fps: job.config.fps
@@ -9455,7 +9455,7 @@ async function runProbeStage(input) {
9455
9455
  log.info("Creating capture session...", { attempt, maxAttempts: PROBE_MAX_ATTEMPTS });
9456
9456
  probeSession = await createCaptureSession4(
9457
9457
  fileServer.url,
9458
- join20(workDir, "probe"),
9458
+ join19(workDir, "probe"),
9459
9459
  captureOpts,
9460
9460
  null,
9461
9461
  probeCfg
@@ -9540,7 +9540,7 @@ async function runProbeStage(input) {
9540
9540
  });
9541
9541
  probeSession = await createCaptureSession4(
9542
9542
  fileServer.url,
9543
- join20(workDir, "probe-screenshot"),
9543
+ join19(workDir, "probe-screenshot"),
9544
9544
  captureOpts,
9545
9545
  null,
9546
9546
  { ...probeCfg, forceScreenshot: true }
@@ -9578,7 +9578,7 @@ async function runProbeStage(input) {
9578
9578
  compiled,
9579
9579
  resolutions,
9580
9580
  projectDir,
9581
- join20(workDir, "downloads")
9581
+ join19(workDir, "downloads")
9582
9582
  );
9583
9583
  assertNotAborted();
9584
9584
  composition.videos = compiled.videos;
@@ -9769,7 +9769,7 @@ async function runProbeStage(input) {
9769
9769
  }
9770
9770
  await preflightCompositionAssetMediaTypes({
9771
9771
  projectDir,
9772
- compiledDir: join20(workDir, "compiled"),
9772
+ compiledDir: join19(workDir, "compiled"),
9773
9773
  composition,
9774
9774
  signal: abortSignal
9775
9775
  });
@@ -9904,7 +9904,7 @@ function validateRenderDuration(input) {
9904
9904
 
9905
9905
  // src/services/render/stages/extractVideosStage.ts
9906
9906
  import { existsSync as existsSync13 } from "node:fs";
9907
- import { join as join21 } from "node:path";
9907
+ import { join as join20 } from "node:path";
9908
9908
  import {
9909
9909
  classifyVideoExtractionError,
9910
9910
  createFrameLookupTable as createFrameLookupTable3,
@@ -10245,14 +10245,14 @@ async function runExtractVideosStage(input) {
10245
10245
  // because short boundary counts can differ by one frame.
10246
10246
  {
10247
10247
  fps: job.config.fps,
10248
- outputDir: join21(compiledDir, "__hyperframes_video_frames"),
10248
+ outputDir: join20(compiledDir, "__hyperframes_video_frames"),
10249
10249
  format: job.config.videoFrameFormat ?? "auto",
10250
10250
  toneMapHdrToSdr: rendersSdrOnly(job.config, composition),
10251
10251
  timelineEnd: composition.duration,
10252
10252
  maxTransientRetries: extractionPolicy.maxTransientRetries,
10253
10253
  collectProbeFailures: extractionPolicy.failureMode === "enforce",
10254
10254
  deferRangeExtraction,
10255
- contentKeyedDirs: [join21(compiledDir, REMOTE_MEDIA_SUBDIR)],
10255
+ contentKeyedDirs: [join20(compiledDir, REMOTE_MEDIA_SUBDIR)],
10256
10256
  urlByAbsentLocalPath,
10257
10257
  onProgress: ({ planned = 0, done = 0 }) => {
10258
10258
  framesPlanned += planned;
@@ -10435,7 +10435,7 @@ async function planVideoLayerPassthrough(input) {
10435
10435
 
10436
10436
  // src/services/render/stages/audioStage.ts
10437
10437
  import { existsSync as existsSync16 } from "node:fs";
10438
- import { join as join24 } from "node:path";
10438
+ import { join as join23 } from "node:path";
10439
10439
  import {
10440
10440
  MIXED_AUDIO_FILENAME,
10441
10441
  audioFailureDiagnostics,
@@ -10446,7 +10446,7 @@ import {
10446
10446
 
10447
10447
  // src/services/render/audioDeliveryLimit.ts
10448
10448
  import { existsSync as existsSync15 } from "node:fs";
10449
- import { dirname as dirname10, join as join23 } from "node:path";
10449
+ import { dirname as dirname10, join as join22 } from "node:path";
10450
10450
  import {
10451
10451
  applyAudioFxChain,
10452
10452
  describeFfmpegFailure as describeFfmpegFailure3,
@@ -10456,8 +10456,7 @@ import {
10456
10456
 
10457
10457
  // src/services/render/audioPadTrim.ts
10458
10458
  import { spawn } from "node:child_process";
10459
- import { mkdtempSync as mkdtempSync3 } from "node:fs";
10460
- import { dirname as dirname9, join as join22 } from "node:path";
10459
+ import { dirname as dirname9, join as join21 } from "node:path";
10461
10460
  import {
10462
10461
  DEFAULT_CONFIG,
10463
10462
  describeFfmpegFailure as describeFfmpegFailure2,
@@ -10564,6 +10563,7 @@ async function measureTruePeakDbfs(audioPath, options) {
10564
10563
  }
10565
10564
 
10566
10565
  // src/services/render/audioPadTrim.ts
10566
+ import { createStagingDir as createStagingDir3 } from "@hyperframes/core/atomic-file";
10567
10567
  var AUDIO_DURATION_TOLERANCE_SECONDS = 1e-3;
10568
10568
  var AAC_DELIVERY_TRUE_PEAK_DBFS = -1;
10569
10569
  var AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB = 0.5;
@@ -10736,7 +10736,7 @@ async function constrainAacTruePeak(input) {
10736
10736
  }
10737
10737
  async function cutSource(input, scratchDir, attenuationDb) {
10738
10738
  if (!input.sourcePath || !input.rewriteSource) return true;
10739
- const cutPath = join22(scratchDir, "source.wav");
10739
+ const cutPath = join21(scratchDir, "source.wav");
10740
10740
  try {
10741
10741
  const result = await input.rewriteSource(input.sourcePath, cutPath, gainFilter(attenuationDb));
10742
10742
  if (!result.success) throw new Error(result.error);
@@ -10750,8 +10750,8 @@ async function cutSource(input, scratchDir, attenuationDb) {
10750
10750
  async function enforceAacTruePeak(input) {
10751
10751
  let scratchDir;
10752
10752
  try {
10753
- scratchDir = mkdtempSync3(join22(dirname9(input.audioPath), ".true-peak-"));
10754
- const correctedPath = join22(scratchDir, "audio.m4a");
10753
+ scratchDir = createStagingDir3(dirname9(input.audioPath), ".true-peak-");
10754
+ const correctedPath = join21(scratchDir, "audio.m4a");
10755
10755
  const measurements = [];
10756
10756
  let attenuationDb = 0;
10757
10757
  let sourcePeakDbfs;
@@ -10961,7 +10961,7 @@ async function limitDeliveryPeaks(input, deps = {
10961
10961
  const peak = await deps.measure(audioPath, { timeoutMs, signal });
10962
10962
  if (peak <= AAC_DELIVERY_TRUE_PEAK_DBFS) return { success: true };
10963
10963
  const alternating = ["a", "b"].map(
10964
- (k) => join23(dirname10(sourcePath), `audio-source-limited-${k}.wav`)
10964
+ (k) => join22(dirname10(sourcePath), `audio-source-limited-${k}.wav`)
10965
10965
  );
10966
10966
  let encodedFrom;
10967
10967
  let ceiling = AAC_DELIVERY_TRUE_PEAK_DBFS;
@@ -11033,7 +11033,7 @@ function runAudioStage(input) {
11033
11033
  }
11034
11034
  async function runAudioStageScoped(input) {
11035
11035
  const stageStart = Date.now();
11036
- const pcmSourcePath = join24(input.workDir, "audio-source.wav");
11036
+ const pcmSourcePath = join23(input.workDir, "audio-source.wav");
11037
11037
  const duration = input.totalFrames * input.fps.den / input.fps.num;
11038
11038
  let deliverySourcePath;
11039
11039
  try {
@@ -11098,7 +11098,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
11098
11098
  assertNotAborted,
11099
11099
  log
11100
11100
  } = input;
11101
- const audioOutputPath = join24(workDir, MIXED_AUDIO_FILENAME);
11101
+ const audioOutputPath = join23(workDir, MIXED_AUDIO_FILENAME);
11102
11102
  let hasAudio = false;
11103
11103
  let audioError;
11104
11104
  let audioFailures;
@@ -11109,7 +11109,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
11109
11109
  audioResult = await processCompositionAudio(
11110
11110
  audios,
11111
11111
  projectDir,
11112
- join24(workDir, "audio-work"),
11112
+ join23(workDir, "audio-work"),
11113
11113
  audioOutputPath,
11114
11114
  duration,
11115
11115
  abortSignal,
@@ -11178,7 +11178,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
11178
11178
 
11179
11179
  // src/services/render/stages/captureStage.ts
11180
11180
  import { existsSync as existsSync17, readdirSync as readdirSync4, statfsSync as statfsSync2 } from "node:fs";
11181
- import { join as join25 } from "node:path";
11181
+ import { join as join24 } from "node:path";
11182
11182
  import {
11183
11183
  classifyCaptureFailure as classifyCaptureFailure2,
11184
11184
  frameFileExtension,
@@ -11251,13 +11251,13 @@ function measureCaptureFrameBytes(workDir, framesDir) {
11251
11251
  if (!existsSync17(workDir)) return total;
11252
11252
  for (const attempt of readdirSync4(workDir)) {
11253
11253
  if (/^retry-\d+-batch-\d+-worker-\d+$/.test(attempt)) {
11254
- total += sampleDirectoryBytes(join25(workDir, attempt));
11254
+ total += sampleDirectoryBytes(join24(workDir, attempt));
11255
11255
  continue;
11256
11256
  }
11257
11257
  if (!/^capture-attempt-\d+$/.test(attempt)) continue;
11258
- const attemptDir = join25(workDir, attempt);
11258
+ const attemptDir = join24(workDir, attempt);
11259
11259
  for (const name of readdirSync4(attemptDir)) {
11260
- if (/^worker-\d+$/.test(name)) total += sampleDirectoryBytes(join25(attemptDir, name));
11260
+ if (/^worker-\d+$/.test(name)) total += sampleDirectoryBytes(join24(attemptDir, name));
11261
11261
  }
11262
11262
  }
11263
11263
  return total;
@@ -11556,7 +11556,7 @@ async function captureSessionFrames(session, { input, rangeStart, rangeEnd, resu
11556
11556
 
11557
11557
  // src/services/render/stages/captureHdrStage.ts
11558
11558
  import { existsSync as existsSync19, mkdirSync as mkdirSync10 } from "node:fs";
11559
- import { join as join29 } from "node:path";
11559
+ import { join as join28 } from "node:path";
11560
11560
  import {
11561
11561
  closeCaptureSession as closeCaptureSession7,
11562
11562
  cloneCaptureWarnings as cloneCaptureWarnings2,
@@ -11628,7 +11628,7 @@ function createHdrImageTransferCache(options = {}) {
11628
11628
  }
11629
11629
 
11630
11630
  // src/services/render/stages/captureHdrSequentialLoop.ts
11631
- import { join as join26 } from "node:path";
11631
+ import { join as join25 } from "node:path";
11632
11632
  import {
11633
11633
  TRANSITIONS,
11634
11634
  crossfade
@@ -11753,7 +11753,7 @@ async function runSequentialLayeredFrameLoop(input) {
11753
11753
  );
11754
11754
  if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
11755
11755
  writeFileExclusiveSync(
11756
- join26(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
11756
+ join25(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
11757
11757
  normalCanvas
11758
11758
  );
11759
11759
  }
@@ -11785,7 +11785,7 @@ async function runSequentialLayeredFrameLoop(input) {
11785
11785
  }
11786
11786
 
11787
11787
  // src/services/render/stages/captureHdrHybridLoop.ts
11788
- import { join as join28 } from "node:path";
11788
+ import { join as join27 } from "node:path";
11789
11789
  import {
11790
11790
  TRANSITIONS as TRANSITIONS2,
11791
11791
  closeCaptureSession as closeCaptureSession6,
@@ -11799,7 +11799,7 @@ import {
11799
11799
  // src/services/shaderTransitionWorkerPool.ts
11800
11800
  import { Worker } from "node:worker_threads";
11801
11801
  import { fileURLToPath as fileURLToPath3, pathToFileURL } from "node:url";
11802
- import { dirname as dirname11, join as join27 } from "node:path";
11802
+ import { dirname as dirname11, join as join26 } from "node:path";
11803
11803
  import { createRequire } from "node:module";
11804
11804
  import { existsSync as existsSync18 } from "node:fs";
11805
11805
  import { cpus as cpus2 } from "node:os";
@@ -11813,9 +11813,9 @@ function resolveWorkerEntry(explicit) {
11813
11813
  return { path: override, isTs };
11814
11814
  }
11815
11815
  const moduleDir = dirname11(fileURLToPath3(import.meta.url));
11816
- const jsPath = join27(moduleDir, "shaderTransitionWorker.js");
11816
+ const jsPath = join26(moduleDir, "shaderTransitionWorker.js");
11817
11817
  if (existsSync18(jsPath)) return { path: jsPath, isTs: false };
11818
- const tsPath = join27(moduleDir, "shaderTransitionWorker.ts");
11818
+ const tsPath = join26(moduleDir, "shaderTransitionWorker.ts");
11819
11819
  return { path: tsPath, isTs: true };
11820
11820
  }
11821
11821
  function buildExecArgv(entryIsTs) {
@@ -12183,7 +12183,7 @@ async function runHybridLayeredFrameLoop(input) {
12183
12183
  );
12184
12184
  if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
12185
12185
  writeFileExclusiveSync(
12186
- join28(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
12186
+ join27(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
12187
12187
  canvas
12188
12188
  );
12189
12189
  }
@@ -12374,7 +12374,7 @@ async function runCaptureHdrStage(input) {
12374
12374
  if (hdrVideoFrameSources.has(v.id)) hdrVideoEndTimes.set(v.id, v.end);
12375
12375
  }
12376
12376
  const debugDumpEnabled = process.env.KEEP_TEMP === "1";
12377
- const debugDumpDir = debugDumpEnabled ? join29(framesDir, "debug-composite") : null;
12377
+ const debugDumpDir = debugDumpEnabled ? join28(framesDir, "debug-composite") : null;
12378
12378
  if (debugDumpDir && !existsSync19(debugDumpDir)) {
12379
12379
  mkdirSync10(debugDumpDir, { recursive: true });
12380
12380
  }
@@ -12541,7 +12541,7 @@ import {
12541
12541
  writeFileSync as writeFileSync6
12542
12542
  } from "node:fs";
12543
12543
  import { readFile as readFile2 } from "node:fs/promises";
12544
- import { dirname as dirname12, join as join30 } from "node:path";
12544
+ import { dirname as dirname12, join as join29 } from "node:path";
12545
12545
  import {
12546
12546
  encodeFramesChunkedConcat,
12547
12547
  encodeFramesFromDir,
@@ -12752,7 +12752,7 @@ function encodeWhileCapturing(input, totalFrames) {
12752
12752
  await new Promise((resolve11) => wake = resolve11);
12753
12753
  }
12754
12754
  if (signal.aborted) return;
12755
- const mergedPath = join30(input.framesDir, formatCaptureFrameName(next, "jpg"));
12755
+ const mergedPath = join29(input.framesDir, formatCaptureFrameName(next, "jpg"));
12756
12756
  const frame = await readLandedFrame(landed.get(next), mergedPath);
12757
12757
  landed.delete(next);
12758
12758
  if (!await stream.writeFrame(frame)) {
@@ -12835,11 +12835,11 @@ async function runEncodeStage(input) {
12835
12835
  );
12836
12836
  }
12837
12837
  captured.forEach((name, i) => {
12838
- const dst = join30(outputPath, formatExportFrameName(i, "png"));
12839
- copyFileSync4(join30(framesDir, name), dst);
12838
+ const dst = join29(outputPath, formatExportFrameName(i, "png"));
12839
+ copyFileSync4(join29(framesDir, name), dst);
12840
12840
  });
12841
12841
  if (hasAudio && audioOutputPath && existsSync20(audioOutputPath)) {
12842
- copyFileSync4(audioOutputPath, join30(outputPath, MIXED_AUDIO_FILENAME2));
12842
+ copyFileSync4(audioOutputPath, join29(outputPath, MIXED_AUDIO_FILENAME2));
12843
12843
  log.info(
12844
12844
  `[Render] png-sequence: ${MIXED_AUDIO_FILENAME2} sidecar written to ${outputPath}/${MIXED_AUDIO_FILENAME2}`
12845
12845
  );
@@ -12859,7 +12859,7 @@ async function runEncodeStage(input) {
12859
12859
  const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
12860
12860
  fps: job.config.fps,
12861
12861
  loop,
12862
- palettePath: join30(dirname12(videoOnlyPath), "gif-palette.png"),
12862
+ palettePath: join29(dirname12(videoOnlyPath), "gif-palette.png"),
12863
12863
  preserveAlpha: needsAlpha,
12864
12864
  signal: abortSignal,
12865
12865
  timeout: engineCfg.ffmpegEncodeTimeout
@@ -13070,7 +13070,7 @@ function sampleDirectoryBytes(dir) {
13070
13070
  continue;
13071
13071
  }
13072
13072
  for (const name of entries) {
13073
- const full = join31(current, name);
13073
+ const full = join30(current, name);
13074
13074
  try {
13075
13075
  const st = statSync9(full);
13076
13076
  if (st.isDirectory()) {
@@ -13226,7 +13226,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
13226
13226
  const ranges = [];
13227
13227
  let rangeStart = null;
13228
13228
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
13229
- const framePath = join31(framesDir, formatCaptureFrameName(frameIndex, frameExt));
13229
+ const framePath = join30(framesDir, formatCaptureFrameName(frameIndex, frameExt));
13230
13230
  const missing = !existsSync21(framePath) || statSync9(framePath).size <= 8;
13231
13231
  if (missing && rangeStart === null) {
13232
13232
  rangeStart = frameIndex;
@@ -13243,7 +13243,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
13243
13243
  function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, rangeStart = 0, stride = 1) {
13244
13244
  const workersPerBatch = Math.max(1, Math.floor(maxWorkers));
13245
13245
  const batches = [];
13246
- const outputDirFor = (batchIndex, workerId) => join31(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`);
13246
+ const outputDirFor = (batchIndex, workerId) => join30(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`);
13247
13247
  if (stride > 1) {
13248
13248
  const spans = /* @__PURE__ */ new Map();
13249
13249
  for (const range of ranges) {
@@ -13303,8 +13303,8 @@ function getNextRetryWorkerCount(currentWorkers) {
13303
13303
  return Math.max(1, Math.floor(currentWorkers / 2));
13304
13304
  }
13305
13305
  function resolveRenderWorkDirPrefix(outputPath, jobId, platform2 = process.platform, systemTempDir = tmpdir2()) {
13306
- if (platform2 === "win32" || platform2 === "darwin") return join31(systemTempDir, "hf-render-");
13307
- return join31(dirname13(outputPath), `work-${jobId}-`);
13306
+ if (platform2 === "win32" || platform2 === "darwin") return join30(systemTempDir, "hf-render-");
13307
+ return join30(dirname13(outputPath), `work-${jobId}-`);
13308
13308
  }
13309
13309
  var MAX_TRANSIENT_CAPTURE_RETRIES = 1;
13310
13310
  function isTransientCaptureRetryEligible(failureKind, missing, retriesUsed) {
@@ -13351,7 +13351,7 @@ The composition is too large for the available memory. To reduce memory pressure
13351
13351
  function countCapturedFrames(totalFrames, framesDir, frameExt) {
13352
13352
  let captured = 0;
13353
13353
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
13354
- const framePath = join31(framesDir, formatCaptureFrameName(frameIndex, frameExt));
13354
+ const framePath = join30(framesDir, formatCaptureFrameName(frameIndex, frameExt));
13355
13355
  if (existsSync21(framePath)) captured++;
13356
13356
  }
13357
13357
  return captured;
@@ -13377,7 +13377,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
13377
13377
  reason: attempt === 0 ? "initial" : pendingTransientRetry ? "transient-retry" : "retry"
13378
13378
  });
13379
13379
  pendingTransientRetry = false;
13380
- const attemptWorkDir = join31(options.workDir, `capture-attempt-${attempt}`);
13380
+ const attemptWorkDir = join30(options.workDir, `capture-attempt-${attempt}`);
13381
13381
  const batches = missingRanges ? buildMissingFrameRetryBatches(
13382
13382
  missingRanges,
13383
13383
  currentWorkers,
@@ -14010,7 +14010,7 @@ function deVerifyFallbackTelemetry(err) {
14010
14010
  }
14011
14011
  function resolveRenderDebugDir() {
14012
14012
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve8(process.env.PRODUCER_RENDERS_DIR, "..") : resolve8(dirname13(fileURLToPath4(import.meta.url)), "../..");
14013
- return join31(producerRoot, ".debug");
14013
+ return join30(producerRoot, ".debug");
14014
14014
  }
14015
14015
  async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal, assertRenderActive) {
14016
14016
  validateHlsRenderConfig(job.config);
@@ -14018,10 +14018,10 @@ async function executeRenderJob(job, projectDir, outputPath, progressSink, abort
14018
14018
  const debugDir = resolveRenderDebugDir();
14019
14019
  const outputDir = dirname13(outputPath);
14020
14020
  if (!existsSync21(outputDir)) mkdirSync12(outputDir, { recursive: true });
14021
- const workDir = job.config.debug ? join31(debugDir, job.id) : createRenderWorkDir(resolveRenderWorkDirPrefix(outputPath, job.id), outputDir);
14021
+ const workDir = job.config.debug ? join30(debugDir, job.id) : createRenderWorkDir(resolveRenderWorkDirPrefix(outputPath, job.id), outputDir);
14022
14022
  const pipelineStart = Date.now();
14023
14023
  const baseLog = job.config.logger ?? defaultLogger;
14024
- const logPath = job.config.debug ? join31(workDir, "render.log") : null;
14024
+ const logPath = job.config.debug ? join30(workDir, "render.log") : null;
14025
14025
  const execution = new RenderExecutionContext({
14026
14026
  request: { renderJobId: job.id, projectDir, outputPath },
14027
14027
  logger: logPath ? createRenderFileLogger(logPath, baseLog) : baseLog,
@@ -14083,7 +14083,7 @@ async function executeRenderPipeline(input) {
14083
14083
  imageDecodeFailures: 0
14084
14084
  };
14085
14085
  let hdrPerf;
14086
- const perfOutputPath = join31(workDir, "perf-summary.json");
14086
+ const perfOutputPath = join30(workDir, "perf-summary.json");
14087
14087
  const cfg = { ...job.config.producerConfig ?? resolveConfig2() };
14088
14088
  const observability = new RenderObservabilityRecorder({
14089
14089
  pipelineStartMs: pipelineStart,
@@ -14188,7 +14188,7 @@ async function executeRenderPipeline(input) {
14188
14188
  requestedWorkers: job.config.workers ?? "auto"
14189
14189
  });
14190
14190
  const entryFile = job.config.entryFile || "index.html";
14191
- const htmlPath = join31(projectDir, entryFile);
14191
+ const htmlPath = join30(projectDir, entryFile);
14192
14192
  if (!existsSync21(htmlPath)) {
14193
14193
  throw new Error(`Entry file not found: ${htmlPath}`);
14194
14194
  }
@@ -14365,7 +14365,7 @@ async function executeRenderPipeline(input) {
14365
14365
  canvas: { width, height },
14366
14366
  page: probeSession.page,
14367
14367
  projectDir,
14368
- compiledDir: join31(workDir, "compiled")
14368
+ compiledDir: join30(workDir, "compiled")
14369
14369
  });
14370
14370
  if (videoLayerPlan.videoId === void 0) {
14371
14371
  log.info(`[Render] Video layer passthrough off: ${videoLayerPlan.reason}`);
@@ -14383,7 +14383,7 @@ async function executeRenderPipeline(input) {
14383
14383
  updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress, {
14384
14384
  code: "extract_video"
14385
14385
  });
14386
- const compiledDir = join31(workDir, "compiled");
14386
+ const compiledDir = join30(workDir, "compiled");
14387
14387
  const segmentsCapture = (layeredOrEffectRoute) => shouldSegmentCapture({
14388
14388
  env: process.env,
14389
14389
  durationSeconds: probeResult.duration,
@@ -14514,7 +14514,7 @@ async function executeRenderPipeline(input) {
14514
14514
  try {
14515
14515
  fileServer = await createFileServer({
14516
14516
  projectDir,
14517
- compiledDir: join31(workDir, "compiled"),
14517
+ compiledDir: join30(workDir, "compiled"),
14518
14518
  port: 0,
14519
14519
  preHeadScripts: [VIRTUAL_TIME_SHIM],
14520
14520
  fps: job.config.fps
@@ -14532,7 +14532,7 @@ async function executeRenderPipeline(input) {
14532
14532
  if (!activeFileServer) {
14533
14533
  throw new Error("File server failed to initialize before frame capture");
14534
14534
  }
14535
- const framesDir = join31(workDir, "captured-frames");
14535
+ const framesDir = join30(workDir, "captured-frames");
14536
14536
  if (!existsSync21(framesDir)) mkdirSync12(framesDir, { recursive: true });
14537
14537
  updateJobStatus(job, "rendering", "Checking browser GPU", 25, onProgress, {
14538
14538
  code: "start_browsers"
@@ -15096,7 +15096,7 @@ async function executeRenderPipeline(input) {
15096
15096
  hls: ".mp4"
15097
15097
  };
15098
15098
  const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
15099
- const videoOnlyPath = join31(workDir, `video-only${videoExt}`);
15099
+ const videoOnlyPath = join30(workDir, `video-only${videoExt}`);
15100
15100
  const usePageSideCompositingForTransitions = (cfg.enablePageSideCompositing || isGif) && compiled.hasShaderTransitions && !hasHdrContent && outputSupportsPageSideShaderCompositing(outputFormat);
15101
15101
  if (usePageSideCompositingForTransitions) {
15102
15102
  activeFileServer.addPreHeadScript(HF_PAGE_SIDE_COMPOSITING_STUB);
@@ -15382,7 +15382,7 @@ async function executeRenderPipeline(input) {
15382
15382
  pageMotionBlur: job.config.pageMotionBlur,
15383
15383
  captureQuality: captureOptions.quality
15384
15384
  });
15385
- const segmentDir = segmentDirFor(join31(projectDir, "renders"), segmentPlanHash);
15385
+ const segmentDir = segmentDirFor(join30(projectDir, "renders"), segmentPlanHash);
15386
15386
  let completedSegments = /* @__PURE__ */ new Set();
15387
15387
  if (job.config.resumeSegments === true) {
15388
15388
  const existing = readSegmentManifest(segmentDir);
@@ -16005,7 +16005,7 @@ async function executeRenderPipeline(input) {
16005
16005
  }
16006
16006
  if (job.config.debug) {
16007
16007
  if (!isPngSequence && !isHls && existsSync21(stagedOutputPath)) {
16008
- const debugOutput = join31(workDir, `output${videoExt}`);
16008
+ const debugOutput = join30(workDir, `output${videoExt}`);
16009
16009
  copyFileSync5(stagedOutputPath, debugOutput);
16010
16010
  }
16011
16011
  }
@@ -16124,7 +16124,7 @@ import {
16124
16124
  closeSync as closeSync5,
16125
16125
  constants as constants3
16126
16126
  } from "node:fs";
16127
- import { resolve as resolve9, join as join32, relative as relative3, isAbsolute as isAbsolute3, sep as sep3 } from "node:path";
16127
+ import { resolve as resolve9, join as join31, relative as relative3, isAbsolute as isAbsolute3, sep as sep3 } from "node:path";
16128
16128
  import { lintHyperframeHtml } from "@hyperframes/lint";
16129
16129
  function isStringRecord(value) {
16130
16130
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -16192,7 +16192,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
16192
16192
  }
16193
16193
  }
16194
16194
  return {
16195
- error: `No HTML entry file found in project directory: ${join32(absProjectDir, preferredEntryFile || "index.html")}`
16195
+ error: `No HTML entry file found in project directory: ${join31(absProjectDir, preferredEntryFile || "index.html")}`
16196
16196
  };
16197
16197
  }
16198
16198
  function prepareHyperframeLintBody(body) {
@@ -16238,7 +16238,7 @@ async function runHyperframeLint(prepared) {
16238
16238
  // src/services/healthWorker.ts
16239
16239
  import { Worker as Worker2 } from "node:worker_threads";
16240
16240
  import { fileURLToPath as fileURLToPath5 } from "node:url";
16241
- import { dirname as dirname14, join as join33 } from "node:path";
16241
+ import { dirname as dirname14, join as join32 } from "node:path";
16242
16242
  import { existsSync as existsSync23 } from "node:fs";
16243
16243
  var DEFAULT_HEALTH_PORT = 9848;
16244
16244
  async function startHealthWorker(options = {}) {
@@ -16314,7 +16314,7 @@ function defaultLogger2() {
16314
16314
  }
16315
16315
  function resolveWorkerEntry2() {
16316
16316
  const here = dirname14(fileURLToPath5(import.meta.url));
16317
- const candidates = [join33(here, "healthWorkerThread.js"), join33(here, "healthWorkerThread.ts")];
16317
+ const candidates = [join32(here, "healthWorkerThread.js"), join32(here, "healthWorkerThread.ts")];
16318
16318
  for (const candidate of candidates) {
16319
16319
  if (existsSync23(candidate)) return candidate;
16320
16320
  }
@@ -16356,7 +16356,7 @@ import {
16356
16356
  createReferenceBackgroundRecorder as createReferenceBackgroundRecorder2
16357
16357
  } from "@hyperframes/engine";
16358
16358
  import { audioFailureDiagnostics as audioFailureDiagnostics3 } from "@hyperframes/engine";
16359
- import { extname as extname4, isAbsolute as isAbsolute4, join as join34, relative as relative4, sep as sep4 } from "node:path";
16359
+ import { extname as extname4, isAbsolute as isAbsolute4, join as join33, relative as relative4, sep as sep4 } from "node:path";
16360
16360
  import {
16361
16361
  fpsToNumber as fpsToNumber9,
16362
16362
  HF_COLOR_GRADING_ATTR as HF_COLOR_GRADING_ATTR2
@@ -16454,6 +16454,7 @@ import { appendRenderProvenanceArgs, describeFfmpegFailure as describeFfmpegFail
16454
16454
 
16455
16455
  // src/services/distributed/mp4Stitch.ts
16456
16456
  import { renameWithRetry as renameWithRetry7 } from "@hyperframes/engine";
16457
+ import { createStagingDir as createStagingDir4 } from "@hyperframes/core/atomic-file";
16457
16458
  var SCAN_BYTES = 64 * 1024;
16458
16459
 
16459
16460
  // src/services/distributed/chunkAudio.ts
@@ -16473,9 +16474,9 @@ var PLAN_ROOT_CATEGORY = {
16473
16474
  var PLAN_DIR_SIZE_LIMIT_BYTES = 2 * 1024 * 1024 * 1024;
16474
16475
  var FREEZE_OWNED_PLAN_FILES = [
16475
16476
  "plan.json",
16476
- join34("meta", "composition.json"),
16477
- join34("meta", "encoder.json"),
16478
- join34("meta", "chunks.json")
16477
+ join33("meta", "composition.json"),
16478
+ join33("meta", "encoder.json"),
16479
+ join33("meta", "chunks.json")
16479
16480
  ];
16480
16481
 
16481
16482
  // src/services/distributed/renderConfigValidation.ts
@@ -16931,8 +16932,8 @@ async function resolveInlineRenderHtml(body) {
16931
16932
  }
16932
16933
  function materializeInlineProject(html, options) {
16933
16934
  const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir3();
16934
- const tempProjectDir = mkdtempSync4(join35(tempRoot, "producer-project-"));
16935
- writeFileSync8(join35(tempProjectDir, "index.html"), html, "utf-8");
16935
+ const tempProjectDir = mkdtempSync(join34(tempRoot, "producer-project-"));
16936
+ writeFileSync8(join34(tempProjectDir, "index.html"), html, "utf-8");
16936
16937
  return {
16937
16938
  prepared: {
16938
16939
  input: { projectDir: tempProjectDir, ...options },