@hyperframes/producer 0.8.225 → 0.8.226

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.
@@ -68,7 +68,6 @@ import { audioFailureDiagnostics as audioFailureDiagnostics2 } from "@hyperframe
68
68
  import {
69
69
  existsSync as existsSync10,
70
70
  mkdirSync as mkdirSync6,
71
- readFileSync as readFileSync6,
72
71
  readdirSync as readdirSync3,
73
72
  rmSync as rmSync5,
74
73
  statSync as statSync5,
@@ -88,6 +87,7 @@ import {
88
87
  import { HF_AUDIO_GROUP_TAG } from "@hyperframes/core/audio-groups";
89
88
  import { extractStandaloneEntryFromIndex, isTemplateEntry } from "@hyperframes/core/compiler";
90
89
  import { HTML_BODY_CSS_HEIGHT_FIRST_RE, HTML_BODY_CSS_WIDTH_FIRST_RE } from "@hyperframes/parsers";
90
+ import { readTextFile as readTextFile2 } from "@hyperframes/parsers/asset-resolution";
91
91
  import {
92
92
  extractMediaMetadata as extractMediaMetadata4,
93
93
  resolveConfig as resolveConfig2,
@@ -1893,7 +1893,7 @@ import { suggestMatchingPreset } from "@hyperframes/core";
1893
1893
  // src/services/htmlCompiler.ts
1894
1894
  import { decodedUrlPath } from "@hyperframes/parsers/asset-paths";
1895
1895
  import { createHash as createHash4 } from "node:crypto";
1896
- import { createReadStream as createReadStream2, existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4 } from "fs";
1896
+ import { createReadStream as createReadStream2, existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
1897
1897
  import { join as join6, dirname as dirname5, resolve as resolve6, basename as basename3, relative as relative2 } from "path";
1898
1898
  import { parseHTML as parseHTML5 } from "linkedom";
1899
1899
  import {
@@ -1946,7 +1946,8 @@ import {
1946
1946
  } from "@hyperframes/parsers/sub-composition-validity";
1947
1947
  import {
1948
1948
  isUnresolvedAssetPlaceholder,
1949
- readProjectFile
1949
+ readProjectFile,
1950
+ readTextFile
1950
1951
  } from "@hyperframes/parsers/asset-resolution";
1951
1952
 
1952
1953
  // src/services/renderMediaCollector.ts
@@ -4035,11 +4036,7 @@ function rebaseDirectEntryAssetPaths(html, projectDir, htmlPath) {
4035
4036
  return document2.toString();
4036
4037
  }
4037
4038
  async function compileForRender(projectDir, htmlPath, downloadDir, options = {}) {
4038
- const entryHtml = rebaseDirectEntryAssetPaths(
4039
- readFileSync4(htmlPath, "utf-8"),
4040
- projectDir,
4041
- htmlPath
4042
- );
4039
+ const entryHtml = rebaseDirectEntryAssetPaths(readTextFile(htmlPath), projectDir, htmlPath);
4043
4040
  const rawHtml = rewriteUnresolvableGsapToCdn(entryHtml, projectDir);
4044
4041
  assertSubCompositionsUsable(rawHtml, projectDir);
4045
4042
  const probes = /* @__PURE__ */ new Map();
@@ -4890,7 +4887,7 @@ async function runProbeStage(input) {
4890
4887
  );
4891
4888
  const hasVariableMedia = hasVariableBoundMedia(compiled.html, job.config.variables);
4892
4889
  const hasInsertedMedia = hasRuntimeMediaChanges(compiled.html);
4893
- const needsBrowser = probeRequiresBrowser({
4890
+ const needsBrowser = cfg.videoLayerPassthrough || probeRequiresBrowser({
4894
4891
  durationSeconds: composition.duration,
4895
4892
  unresolvedCompositionCount: compiled.unresolvedCompositions.length,
4896
4893
  hasAutoStart,
@@ -5522,17 +5519,23 @@ function resolveVideoExtractionPolicy(env = process.env) {
5522
5519
  const maxTransientRetries = failureMode !== "off" && env.HF_VIDEO_EXTRACTION_MAX_RETRIES?.trim() === "1" ? 1 : 0;
5523
5520
  return { failureMode, maxTransientRetries };
5524
5521
  }
5522
+ var MAX_NAMED_SOURCES = 5;
5525
5523
  var VideoExtractionStageError = class extends Error {
5526
5524
  constructor(code, retryable, failures, extractionFailure = buildExtractionFailureMetadata(
5527
5525
  failures.map((failure) => ({
5528
5526
  kind: failure.kind,
5529
5527
  affectedElementCount: failure.count
5530
5528
  }))
5531
- ), ffmpegReason) {
5529
+ ), ffmpegReason, sources = []) {
5532
5530
  const total = failures.reduce((sum2, failure) => sum2 + failure.count, 0);
5533
5531
  const breakdown = failures.map((failure) => `${failure.kind}=${failure.count}`).join(",");
5534
5532
  const reason = ffmpegReason ? `: ffmpeg said: ${ffmpegReason}` : "";
5535
- super(`Video extraction failed for ${total} source(s) [${code}; ${breakdown}]${reason}`);
5533
+ const shown = sources.slice(0, MAX_NAMED_SOURCES).join(", ");
5534
+ const more = sources.length > MAX_NAMED_SOURCES ? ` and ${sources.length - MAX_NAMED_SOURCES} more` : "";
5535
+ const files = sources.length > 0 ? ` (${shown}${more})` : "";
5536
+ super(
5537
+ `Video extraction failed for ${total} source(s) [${code}; ${breakdown}]${files}${reason}`
5538
+ );
5536
5539
  this.code = code;
5537
5540
  this.retryable = retryable;
5538
5541
  this.failures = failures;
@@ -5580,7 +5583,10 @@ function buildVideoExtractionStageError(result) {
5580
5583
  retryable,
5581
5584
  failures,
5582
5585
  extractionFailureMetadataFromResult(result),
5583
- result.errors.find((failure) => failure.ffmpegReason)?.ffmpegReason
5586
+ result.errors.find((failure) => failure.ffmpegReason)?.ffmpegReason,
5587
+ [
5588
+ ...new Set(result.errors.flatMap((failure) => failure.source ? [failure.source] : []))
5589
+ ].sort()
5584
5590
  );
5585
5591
  }
5586
5592
  function buildHdrProbeStageError(failures) {
@@ -5659,7 +5665,8 @@ async function runExtractVideosStage(input) {
5659
5665
  assertNotAborted,
5660
5666
  materializeSymlinks,
5661
5667
  deferRangeExtraction,
5662
- urlByAbsentLocalPath
5668
+ urlByAbsentLocalPath,
5669
+ skipFrameExtractionIds = []
5663
5670
  } = input;
5664
5671
  const stage2Start = Date.now();
5665
5672
  const extractionPolicy = resolveVideoExtractionPolicy();
@@ -5730,7 +5737,10 @@ async function runExtractVideosStage(input) {
5730
5737
  );
5731
5738
  imageColorSpaces.push(...probed);
5732
5739
  }
5733
- if (composition.videos.length > 0) {
5740
+ if (skipFrameExtractionIds.length > 0) {
5741
+ await appendVideoAudioFromProbe({ projectDir, compiledDir, composition, urlByAbsentLocalPath });
5742
+ videoReadinessSkipIds = [...skipFrameExtractionIds];
5743
+ } else if (composition.videos.length > 0) {
5734
5744
  const totalVideos = composition.videos.length;
5735
5745
  for (let i = 0; i < totalVideos; i++) {
5736
5746
  const v = composition.videos[i];
@@ -5854,6 +5864,14 @@ async function appendVideoAudioFromProbe(input) {
5854
5864
  );
5855
5865
  }
5856
5866
 
5867
+ // src/services/render/videoLayerPassthroughPlan.ts
5868
+ import {
5869
+ buildVideoLayerInput,
5870
+ isHttpUrl as isHttpUrl3,
5871
+ qualifyVideoLayer,
5872
+ resolveProjectRelativeSrc as resolveProjectRelativeSrc4
5873
+ } from "@hyperframes/engine";
5874
+
5857
5875
  // src/services/render/stages/audioStage.ts
5858
5876
  import { join as join11 } from "node:path";
5859
5877
  import {
@@ -6856,7 +6874,7 @@ import {
6856
6874
  existsSync as existsSync9,
6857
6875
  mkdirSync as mkdirSync5,
6858
6876
  readdirSync as readdirSync2,
6859
- readFileSync as readFileSync5,
6877
+ readFileSync as readFileSync4,
6860
6878
  rmSync as rmSync4,
6861
6879
  statSync as statSync4,
6862
6880
  writeFileSync as writeFileSync3
@@ -6950,7 +6968,7 @@ async function reencodeWithClearedWholeFrames(argsInput, run, startTime) {
6950
6968
  const error = formatFfmpegError(result.exitCode, result.stderr);
6951
6969
  return gifEncodeFailure(startTime, outputPath, error, result.failureReason);
6952
6970
  }
6953
- const gif = readFileSync5(outputPath);
6971
+ const gif = readFileSync4(outputPath);
6954
6972
  if (!clearGifFramesBeforeNext(gif)) {
6955
6973
  const error = "[FFmpeg] GIF output could not be parsed to clear its frames";
6956
6974
  return gifEncodeFailure(startTime, outputPath, error);
@@ -6983,7 +7001,7 @@ async function encodeGifFromDir(framesDir, framePattern, outputPath, input) {
6983
7001
  return gifEncodeFailure(startTime, outputPath, error, result.failureReason);
6984
7002
  }
6985
7003
  }
6986
- if (input.preserveAlpha && gifClearsAfterLeavingFrameInPlace(readFileSync5(outputPath)) !== false) {
7004
+ if (input.preserveAlpha && gifClearsAfterLeavingFrameInPlace(readFileSync4(outputPath)) !== false) {
6987
7005
  const failure = await reencodeWithClearedWholeFrames(argsInput, run, startTime);
6988
7006
  if (failure) return failure;
6989
7007
  }
@@ -7654,7 +7672,7 @@ import {
7654
7672
  // src/services/distributed/shared.ts
7655
7673
  import { execFile as execFileCallback } from "node:child_process";
7656
7674
  import { dirname as dirname9, join as join15 } from "node:path";
7657
- import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
7675
+ import { existsSync as existsSync11, readFileSync as readFileSync5 } from "node:fs";
7658
7676
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7659
7677
  import { promisify as promisify2 } from "node:util";
7660
7678
  import {
@@ -7933,7 +7951,7 @@ function readProducerVersion() {
7933
7951
  const candidate = join15(current, "package.json");
7934
7952
  if (existsSync11(candidate)) {
7935
7953
  try {
7936
- const pkg = JSON.parse(readFileSync7(candidate, "utf-8"));
7954
+ const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
7937
7955
  if (pkg.name === "@hyperframes/producer" && typeof pkg.version === "string") {
7938
7956
  cachedProducerVersion = pkg.version;
7939
7957
  return pkg.version;
@@ -8263,7 +8281,7 @@ function buildWeightedChunkSlices(weights, chunkCount, minFrames, maxFrames) {
8263
8281
  }
8264
8282
 
8265
8283
  // src/services/render/stages/freezePlan.ts
8266
- import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync8, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
8284
+ import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync6, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
8267
8285
  import { join as join18, relative as relative3, resolve as resolve8 } from "node:path";
8268
8286
 
8269
8287
  // src/services/distributed/planProtocol.ts
@@ -8503,7 +8521,7 @@ function collectPlanAssetShas(planDir, digests) {
8503
8521
  const assets = [];
8504
8522
  for (const file of files) {
8505
8523
  if (file.planRelativePath === COMPILED_INDEX_RELATIVE_PATH) {
8506
- compositionHtml = readFileSync8(file.absolutePath);
8524
+ compositionHtml = readFileSync6(file.absolutePath);
8507
8525
  continue;
8508
8526
  }
8509
8527
  if (HASH_EXCLUDED_PLAN_FILES.has(file.planRelativePath)) continue;
@@ -8527,7 +8545,7 @@ function writePlanRemoteFiles(planDir, files) {
8527
8545
  }
8528
8546
  function readPlanRemoteFiles(planDir) {
8529
8547
  const path = join18(planDir, PLAN_REMOTE_FILES_RELATIVE_PATH);
8530
- return existsSync13(path) ? JSON.parse(readFileSync8(path, "utf-8")) : [];
8548
+ return existsSync13(path) ? JSON.parse(readFileSync6(path, "utf-8")) : [];
8531
8549
  }
8532
8550
  function recomputePlanHashFromPlanDir(planDir, digests) {
8533
8551
  const planJsonPath = join18(planDir, "plan.json");
@@ -8538,8 +8556,8 @@ function recomputePlanHashFromPlanDir(planDir, digests) {
8538
8556
  if (!existsSync13(encoderJsonPath)) {
8539
8557
  throw new Error(`[freezePlan] meta/encoder.json missing: ${encoderJsonPath}`);
8540
8558
  }
8541
- const planJson = JSON.parse(readFileSync8(planJsonPath, "utf-8"));
8542
- const encoderConfigCanonicalJson = readFileSync8(encoderJsonPath, "utf-8");
8559
+ const planJson = JSON.parse(readFileSync6(planJsonPath, "utf-8"));
8560
+ const encoderConfigCanonicalJson = readFileSync6(encoderJsonPath, "utf-8");
8543
8561
  const { compositionHtml, assets } = collectPlanAssetShas(planDir, digests);
8544
8562
  return computePlanHash({
8545
8563
  compositionHtml,
@@ -8645,7 +8663,7 @@ function applyRuntimeEnvSnapshot(snapshot, env = process.env) {
8645
8663
  }
8646
8664
 
8647
8665
  // src/services/distributed/chunkAudio.ts
8648
- import { closeSync as closeSync4, existsSync as existsSync14, ftruncateSync, mkdirSync as mkdirSync9, openSync as openSync4, readFileSync as readFileSync9 } from "node:fs";
8666
+ import { closeSync as closeSync4, existsSync as existsSync14, ftruncateSync, mkdirSync as mkdirSync9, openSync as openSync4, readFileSync as readFileSync7 } from "node:fs";
8649
8667
  import { writeFileSync as writeFileSync6, writeSync } from "node:fs";
8650
8668
  import { join as join20 } from "node:path";
8651
8669
  import { appendRenderProvenanceArgs, describeFfmpegFailure as describeFfmpegFailure3, runFfmpeg as runFfmpeg7 } from "@hyperframes/engine";
@@ -9118,7 +9136,7 @@ async function writeChunkAudioSlices(input) {
9118
9136
  offset += track.sizes[offsets.length - 1];
9119
9137
  }
9120
9138
  });
9121
- const bytes = readFileSync9(input.audioPath);
9139
+ const bytes = readFileSync7(input.audioPath);
9122
9140
  const layout = { sizeBytes: bytes.length, payloadStart, payloadEnd, partStarts: {} };
9123
9141
  mkdirSync9(join20(input.planDir, SLICE_DIR), { recursive: true });
9124
9142
  input.chunks.forEach((_, index) => {
@@ -9137,8 +9155,8 @@ async function writeChunkAudioSlices(input) {
9137
9155
  function chunkAudioSource(planDir, chunkIndex, scratchPath) {
9138
9156
  const layoutPath = join20(planDir, SLICE_LAYOUT);
9139
9157
  if (!existsSync14(layoutPath)) return resolvePlanAudioPath(planDir);
9140
- const layout = JSON.parse(readFileSync9(layoutPath, "utf-8"));
9141
- const frame = readFileSync9(join20(planDir, SLICE_FRAME));
9158
+ const layout = JSON.parse(readFileSync7(layoutPath, "utf-8"));
9159
+ const frame = readFileSync7(join20(planDir, SLICE_FRAME));
9142
9160
  const fd = openSync4(scratchPath, "w");
9143
9161
  try {
9144
9162
  writeSync(fd, frame, 0, layout.payloadStart, 0);
@@ -9151,7 +9169,7 @@ function chunkAudioSource(planDir, chunkIndex, scratchPath) {
9151
9169
  );
9152
9170
  const start = layout.partStarts[chunkIndex];
9153
9171
  if (start !== void 0) {
9154
- const part = readFileSync9(join20(planDir, chunkAudioSlicePath(chunkIndex)));
9172
+ const part = readFileSync7(join20(planDir, chunkAudioSlicePath(chunkIndex)));
9155
9173
  writeSync(fd, part, 0, part.length, start);
9156
9174
  }
9157
9175
  ftruncateSync(fd, layout.sizeBytes);
@@ -10242,7 +10260,7 @@ import {
10242
10260
  lstatSync as lstatSync2,
10243
10261
  mkdirSync as mkdirSync12,
10244
10262
  mkdtempSync as mkdtempSync4,
10245
- readFileSync as readFileSync10,
10263
+ readFileSync as readFileSync8,
10246
10264
  readdirSync as readdirSync7,
10247
10265
  rmSync as rmSync9,
10248
10266
  statSync as statSync7,
@@ -10391,7 +10409,7 @@ function isNonNegativeIntegerArray(value) {
10391
10409
  return Array.isArray(value) && value.every((item) => typeof item === "number" && Number.isInteger(item) && item >= 0);
10392
10410
  }
10393
10411
  function readJsonFile(path, label) {
10394
- const contents = readFileSync10(path, "utf-8");
10412
+ const contents = readFileSync8(path, "utf-8");
10395
10413
  try {
10396
10414
  const parsed = JSON.parse(contents);
10397
10415
  return parsed;
@@ -11132,7 +11150,7 @@ import {
11132
11150
  existsSync as existsSync18,
11133
11151
  mkdirSync as mkdirSync13,
11134
11152
  mkdtempSync as mkdtempSync5,
11135
- readFileSync as readFileSync11,
11153
+ readFileSync as readFileSync9,
11136
11154
  readdirSync as readdirSync8,
11137
11155
  rmSync as rmSync10,
11138
11156
  statSync as statSync8,
@@ -11236,13 +11254,13 @@ function readAssemblePlan(planDir, chunkPaths) {
11236
11254
  if (!existsSync18(planJsonPath)) {
11237
11255
  throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
11238
11256
  }
11239
- const plan2 = JSON.parse(readFileSync11(planJsonPath, "utf-8"));
11257
+ const plan2 = JSON.parse(readFileSync9(planJsonPath, "utf-8"));
11240
11258
  readPlanProtocolV1(plan2, DISTRIBUTED_RENDER_CAPABILITIES.roles.assembler);
11241
11259
  validatePlanV2MaterializedTarget(planDir, { role: "assembler" });
11242
11260
  if (!existsSync18(chunksJsonPath)) {
11243
11261
  throw new Error(`[assemble] planDir missing meta/chunks.json: ${chunksJsonPath}`);
11244
11262
  }
11245
- const chunks = JSON.parse(readFileSync11(chunksJsonPath, "utf-8"));
11263
+ const chunks = JSON.parse(readFileSync9(chunksJsonPath, "utf-8"));
11246
11264
  if (chunkPaths.length !== chunks.length) {
11247
11265
  throw new Error(
11248
11266
  `[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
@@ -11388,13 +11406,13 @@ function stitchesSeparateAudio(planDir) {
11388
11406
  return lockedAudio(planDir).separateAudio === true;
11389
11407
  }
11390
11408
  function planFormat(planDir) {
11391
- const plan2 = JSON.parse(readFileSync11(join26(planDir, "plan.json"), "utf-8"));
11409
+ const plan2 = JSON.parse(readFileSync9(join26(planDir, "plan.json"), "utf-8"));
11392
11410
  return plan2.dimensions.format;
11393
11411
  }
11394
11412
  function lockedAudio(planDir) {
11395
11413
  const encoderJsonPath = join26(planDir, "meta", "encoder.json");
11396
11414
  if (!existsSync18(encoderJsonPath)) return {};
11397
- return JSON.parse(readFileSync11(encoderJsonPath, "utf-8"));
11415
+ return JSON.parse(readFileSync9(encoderJsonPath, "utf-8"));
11398
11416
  }
11399
11417
  function readCfrEncoder(planDir, format) {
11400
11418
  if (format !== "mp4") {
@@ -11406,7 +11424,7 @@ function readCfrEncoder(planDir, format) {
11406
11424
  if (!existsSync18(encoderJsonPath)) {
11407
11425
  throw new Error(`[assemble] planDir missing meta/encoder.json: ${encoderJsonPath}`);
11408
11426
  }
11409
- const encoderJson = JSON.parse(readFileSync11(encoderJsonPath, "utf-8"));
11427
+ const encoderJson = JSON.parse(readFileSync9(encoderJsonPath, "utf-8"));
11410
11428
  if (encoderJson.encoder === "libx265-software") {
11411
11429
  throw new Error(
11412
11430
  `[assemble] cfr=true is not yet supported with codec: "h265". The cfr re-encode pass uses libx264 and would silently transcode the h265 chunks. Either disable cfr or render with codec: "h264".`
@@ -11460,7 +11478,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
11460
11478
 
11461
11479
  // src/services/distributed/renderChunk.ts
11462
11480
  import { randomBytes } from "node:crypto";
11463
- import { existsSync as existsSync19, mkdirSync as mkdirSync14, readFileSync as readFileSync12, readdirSync as readdirSync9, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
11481
+ import { existsSync as existsSync19, mkdirSync as mkdirSync14, readFileSync as readFileSync10, readdirSync as readdirSync9, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
11464
11482
  import { cpus } from "node:os";
11465
11483
  import { join as join27 } from "node:path";
11466
11484
  import {
@@ -11583,10 +11601,10 @@ async function beginFrameSessionNeedsScreenshotFallback(session, probe = probeBe
11583
11601
  return !await probe(session.page, timeoutMs, probeTick, session.beginFrameIntervalMs);
11584
11602
  }
11585
11603
  function hashChunkOutput(outputPath, kind) {
11586
- if (kind === "file") return sha256Hex(readFileSync12(outputPath));
11604
+ if (kind === "file") return sha256Hex(readFileSync10(outputPath));
11587
11605
  const entries = readdirSync9(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
11588
11606
  const lines = entries.map(
11589
- (name) => `${name}\0${sha256Hex(readFileSync12(join27(outputPath, name)))}`
11607
+ (name) => `${name}\0${sha256Hex(readFileSync10(join27(outputPath, name)))}`
11590
11608
  );
11591
11609
  return sha256Hex(lines.join("\0"));
11592
11610
  }
@@ -11612,7 +11630,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
11612
11630
  `[renderChunk] planDir is missing required artifact: ${planJsonPath}`
11613
11631
  );
11614
11632
  }
11615
- const plan2 = JSON.parse(readFileSync12(planJsonPath, "utf-8"));
11633
+ const plan2 = JSON.parse(readFileSync10(planJsonPath, "utf-8"));
11616
11634
  readPlanProtocolV1(plan2, DISTRIBUTED_RENDER_CAPABILITIES.roles.chunk);
11617
11635
  const planHashStarted = Date.now();
11618
11636
  const v2Materialization = readValidatedPlanV2Materialization(planDir, {
@@ -11629,13 +11647,13 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
11629
11647
  );
11630
11648
  }
11631
11649
  }
11632
- const encoder = JSON.parse(readFileSync12(encoderJsonPath, "utf-8"));
11633
- const chunks = JSON.parse(readFileSync12(chunksJsonPath, "utf-8"));
11650
+ const encoder = JSON.parse(readFileSync10(encoderJsonPath, "utf-8"));
11651
+ const chunks = JSON.parse(readFileSync10(chunksJsonPath, "utf-8"));
11634
11652
  const videosJsonPath = join27(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
11635
11653
  let planVideos = null;
11636
11654
  if (existsSync19(videosJsonPath)) {
11637
11655
  try {
11638
- planVideos = validatePlanVideosForChunk(JSON.parse(readFileSync12(videosJsonPath, "utf-8")));
11656
+ planVideos = validatePlanVideosForChunk(JSON.parse(readFileSync10(videosJsonPath, "utf-8")));
11639
11657
  } catch (err) {
11640
11658
  if (err instanceof RenderChunkValidationError) throw err;
11641
11659
  throw new RenderChunkValidationError(
@@ -11746,7 +11764,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
11746
11764
  dimensions: plan2.dimensions,
11747
11765
  encoder,
11748
11766
  videoCount: planVideos?.videos.length ?? 0,
11749
- html: readFileSync12(join27(compiledDir, "index.html"), "utf-8"),
11767
+ html: readFileSync10(join27(compiledDir, "index.html"), "utf-8"),
11750
11768
  // The plan ships a deferred source only to chunks that show it; don't wait on the rest.
11751
11769
  skipReadinessVideoIds: deferredVideos.filter(
11752
11770
  (video) => !shownFrames.get(video.videoId)?.size || remoteVideoIds.has(video.videoId)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "0.1.0",
3
3
  "buildId": "dev",
4
- "sha256": "1503dd37b026878d624c777b74f45676d66598b0f1f927fb419e904de6b54031",
4
+ "sha256": "b146e56ef5aee29f5ac13ce408c9c4e2728aa7c0cbc5b42f4c6526f3e5461b8d",
5
5
  "artifacts": {
6
6
  "iife": "hyperframe.runtime.iife.js",
7
7
  "esm": "hyperframe.runtime.mjs"