@hyperframes/producer 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +79 -62
- package/dist/index.js.map +4 -4
- package/dist/public-server.js +79 -62
- package/dist/public-server.js.map +4 -4
- package/dist/services/htmlCompiler.d.ts.map +1 -1
- package/dist/services/renderOrchestrator.d.ts +5 -0
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/utils/paths.d.ts +35 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -57865,7 +57865,7 @@ var require_util2 = __commonJS({
|
|
|
57865
57865
|
}
|
|
57866
57866
|
path12 = url.path;
|
|
57867
57867
|
}
|
|
57868
|
-
var
|
|
57868
|
+
var isAbsolute3 = exports.isAbsolute(path12);
|
|
57869
57869
|
var parts = path12.split(/\/+/);
|
|
57870
57870
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
57871
57871
|
part = parts[i];
|
|
@@ -57885,7 +57885,7 @@ var require_util2 = __commonJS({
|
|
|
57885
57885
|
}
|
|
57886
57886
|
path12 = parts.join("/");
|
|
57887
57887
|
if (path12 === "") {
|
|
57888
|
-
path12 =
|
|
57888
|
+
path12 = isAbsolute3 ? "/" : ".";
|
|
57889
57889
|
}
|
|
57890
57890
|
if (url) {
|
|
57891
57891
|
url.path = path12;
|
|
@@ -57930,7 +57930,7 @@ var require_util2 = __commonJS({
|
|
|
57930
57930
|
exports.isAbsolute = function(aPath) {
|
|
57931
57931
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
57932
57932
|
};
|
|
57933
|
-
function
|
|
57933
|
+
function relative3(aRoot, aPath) {
|
|
57934
57934
|
if (aRoot === "") {
|
|
57935
57935
|
aRoot = ".";
|
|
57936
57936
|
}
|
|
@@ -57949,7 +57949,7 @@ var require_util2 = __commonJS({
|
|
|
57949
57949
|
}
|
|
57950
57950
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
57951
57951
|
}
|
|
57952
|
-
exports.relative =
|
|
57952
|
+
exports.relative = relative3;
|
|
57953
57953
|
var supportsNullProto = (function() {
|
|
57954
57954
|
var obj = /* @__PURE__ */ Object.create(null);
|
|
57955
57955
|
return !("__proto__" in obj);
|
|
@@ -92714,10 +92714,10 @@ function compareDocumentPosition(nodeA, nodeB) {
|
|
|
92714
92714
|
function uniqueSort(nodes) {
|
|
92715
92715
|
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
|
|
92716
92716
|
nodes.sort((a, b) => {
|
|
92717
|
-
const
|
|
92718
|
-
if (
|
|
92717
|
+
const relative3 = compareDocumentPosition(a, b);
|
|
92718
|
+
if (relative3 & DocumentPosition.PRECEDING) {
|
|
92719
92719
|
return -1;
|
|
92720
|
-
} else if (
|
|
92720
|
+
} else if (relative3 & DocumentPosition.FOLLOWING) {
|
|
92721
92721
|
return 1;
|
|
92722
92722
|
}
|
|
92723
92723
|
return 0;
|
|
@@ -105766,7 +105766,7 @@ var serve = (options, listeningListener) => {
|
|
|
105766
105766
|
};
|
|
105767
105767
|
|
|
105768
105768
|
// src/services/renderOrchestrator.ts
|
|
105769
|
-
import { join as
|
|
105769
|
+
import { join as join15, dirname as dirname10, resolve as resolve10 } from "path";
|
|
105770
105770
|
import { randomUUID } from "crypto";
|
|
105771
105771
|
import { freemem as freemem2 } from "os";
|
|
105772
105772
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -106126,13 +106126,41 @@ function createFileServer2(options) {
|
|
|
106126
106126
|
|
|
106127
106127
|
// src/services/htmlCompiler.ts
|
|
106128
106128
|
import { readFileSync as readFileSync8, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
|
|
106129
|
-
import { join as
|
|
106129
|
+
import { join as join14, dirname as dirname9, resolve as resolve9 } from "path";
|
|
106130
106130
|
import postcss from "postcss";
|
|
106131
106131
|
|
|
106132
|
+
// src/utils/paths.ts
|
|
106133
|
+
import { resolve as resolve8, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
|
|
106134
|
+
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve8(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
106135
|
+
function isPathInside(childPath, parentPath) {
|
|
106136
|
+
const absChild = resolve8(childPath);
|
|
106137
|
+
const absParent = resolve8(parentPath);
|
|
106138
|
+
if (absChild === absParent) return true;
|
|
106139
|
+
const rel = relative2(absParent, absChild);
|
|
106140
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
|
|
106141
|
+
}
|
|
106142
|
+
function toExternalAssetKey(absPath) {
|
|
106143
|
+
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
106144
|
+
let normalised = absPath.replace(/\\/g, "/");
|
|
106145
|
+
normalised = normalised.replace(/^\/\/\?\/UNC\//i, "//");
|
|
106146
|
+
normalised = normalised.replace(/^\/\/\?\//, "");
|
|
106147
|
+
normalised = normalised.replace(/^\/\/([^/]+)\//, "unc/$1/");
|
|
106148
|
+
normalised = normalised.replace(/^\/+/, "");
|
|
106149
|
+
normalised = normalised.replace(/^([A-Za-z]):\/?/, "$1/");
|
|
106150
|
+
return "hf-ext/" + normalised;
|
|
106151
|
+
}
|
|
106152
|
+
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
106153
|
+
const absoluteProjectDir = resolve8(projectDir);
|
|
106154
|
+
const projectName = basename2(absoluteProjectDir);
|
|
106155
|
+
const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
|
|
106156
|
+
const absoluteOutputPath = resolve8(resolvedOutputPath);
|
|
106157
|
+
return { absoluteProjectDir, absoluteOutputPath };
|
|
106158
|
+
}
|
|
106159
|
+
|
|
106132
106160
|
// src/services/deterministicFonts.ts
|
|
106133
106161
|
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
106134
106162
|
import { homedir as homedir2 } from "node:os";
|
|
106135
|
-
import { join as
|
|
106163
|
+
import { join as join13 } from "node:path";
|
|
106136
106164
|
|
|
106137
106165
|
// src/services/fontData.generated.ts
|
|
106138
106166
|
var EMBEDDED_FONT_DATA = /* @__PURE__ */ new Map([
|
|
@@ -106410,20 +106438,20 @@ function warnUnresolvedFonts(unresolved) {
|
|
|
106410
106438
|
Docs: https://hyperframes.heygen.com/docs/fonts`
|
|
106411
106439
|
);
|
|
106412
106440
|
}
|
|
106413
|
-
var GOOGLE_FONTS_CACHE_DIR =
|
|
106441
|
+
var GOOGLE_FONTS_CACHE_DIR = join13(homedir2(), ".cache", "hyperframes", "fonts");
|
|
106414
106442
|
var WOFF2_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
106415
106443
|
function fontSlug(familyName) {
|
|
106416
106444
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
106417
106445
|
}
|
|
106418
106446
|
function fontCacheDir(slug) {
|
|
106419
|
-
const dir =
|
|
106447
|
+
const dir = join13(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
106420
106448
|
if (!existsSync13(dir)) {
|
|
106421
106449
|
mkdirSync8(dir, { recursive: true });
|
|
106422
106450
|
}
|
|
106423
106451
|
return dir;
|
|
106424
106452
|
}
|
|
106425
106453
|
function cachedWoff2Path(slug, weight, style) {
|
|
106426
|
-
return
|
|
106454
|
+
return join13(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
106427
106455
|
}
|
|
106428
106456
|
async function fetchGoogleFont(familyName) {
|
|
106429
106457
|
const slug = fontSlug(familyName);
|
|
@@ -106525,7 +106553,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
106525
106553
|
return { duration: 0, resolvedPath: src };
|
|
106526
106554
|
}
|
|
106527
106555
|
} else if (!filePath.startsWith("/")) {
|
|
106528
|
-
filePath =
|
|
106556
|
+
filePath = join14(baseDir, filePath);
|
|
106529
106557
|
}
|
|
106530
106558
|
if (!existsSync14(filePath)) {
|
|
106531
106559
|
return { duration: 0, resolvedPath: filePath };
|
|
@@ -106591,7 +106619,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
106591
106619
|
const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
|
|
106592
106620
|
const absoluteStart = parentOffset + elStart;
|
|
106593
106621
|
const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
|
|
106594
|
-
const filePath =
|
|
106622
|
+
const filePath = resolve9(projectDir, srcPath);
|
|
106595
106623
|
if (visited.has(filePath)) {
|
|
106596
106624
|
continue;
|
|
106597
106625
|
}
|
|
@@ -106791,7 +106819,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
106791
106819
|
if (!srcPath) continue;
|
|
106792
106820
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
106793
106821
|
if (!compHtml) {
|
|
106794
|
-
const filePath =
|
|
106822
|
+
const filePath = resolve9(projectDir, srcPath);
|
|
106795
106823
|
if (existsSync14(filePath)) {
|
|
106796
106824
|
compHtml = readFileSync8(filePath, "utf-8");
|
|
106797
106825
|
}
|
|
@@ -107004,7 +107032,7 @@ ${safeText}
|
|
|
107004
107032
|
return result;
|
|
107005
107033
|
}
|
|
107006
107034
|
function collectExternalAssets(html, projectDir) {
|
|
107007
|
-
const absProjectDir =
|
|
107035
|
+
const absProjectDir = resolve9(projectDir);
|
|
107008
107036
|
const externalAssets = /* @__PURE__ */ new Map();
|
|
107009
107037
|
const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
|
|
107010
107038
|
function processPath(rawPath) {
|
|
@@ -107012,12 +107040,12 @@ function collectExternalAssets(html, projectDir) {
|
|
|
107012
107040
|
if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
|
|
107013
107041
|
return null;
|
|
107014
107042
|
}
|
|
107015
|
-
const absPath =
|
|
107016
|
-
if (
|
|
107043
|
+
const absPath = resolve9(absProjectDir, trimmed);
|
|
107044
|
+
if (isPathInside(absPath, absProjectDir)) {
|
|
107017
107045
|
return null;
|
|
107018
107046
|
}
|
|
107019
107047
|
if (!existsSync14(absPath)) return null;
|
|
107020
|
-
const safeKey =
|
|
107048
|
+
const safeKey = toExternalAssetKey(absPath);
|
|
107021
107049
|
externalAssets.set(safeKey, absPath);
|
|
107022
107050
|
return safeKey;
|
|
107023
107051
|
}
|
|
@@ -107089,7 +107117,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
107089
107117
|
const audios = dedupeElementsById([...mainAudios, ...subAudios]);
|
|
107090
107118
|
for (const video of videos) {
|
|
107091
107119
|
if (isHttpUrl(video.src)) continue;
|
|
107092
|
-
const videoPath =
|
|
107120
|
+
const videoPath = resolve9(projectDir, video.src);
|
|
107093
107121
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
107094
107122
|
Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
107095
107123
|
if (analysis.isProblematic) {
|
|
@@ -107316,17 +107344,17 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
107316
107344
|
};
|
|
107317
107345
|
}
|
|
107318
107346
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
107319
|
-
const compileDir =
|
|
107347
|
+
const compileDir = join15(workDir, "compiled");
|
|
107320
107348
|
mkdirSync10(compileDir, { recursive: true });
|
|
107321
|
-
writeFileSync4(
|
|
107349
|
+
writeFileSync4(join15(compileDir, "index.html"), compiled.html, "utf-8");
|
|
107322
107350
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
107323
|
-
const outPath =
|
|
107351
|
+
const outPath = join15(compileDir, srcPath);
|
|
107324
107352
|
mkdirSync10(dirname10(outPath), { recursive: true });
|
|
107325
107353
|
writeFileSync4(outPath, html, "utf-8");
|
|
107326
107354
|
}
|
|
107327
107355
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
107328
|
-
const outPath =
|
|
107329
|
-
if (!outPath
|
|
107356
|
+
const outPath = resolve10(join15(compileDir, relativePath));
|
|
107357
|
+
if (!isPathInside(outPath, compileDir)) {
|
|
107330
107358
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
107331
107359
|
continue;
|
|
107332
107360
|
}
|
|
@@ -107354,7 +107382,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
107354
107382
|
})),
|
|
107355
107383
|
subCompositions: Array.from(compiled.subCompositions.keys())
|
|
107356
107384
|
};
|
|
107357
|
-
writeFileSync4(
|
|
107385
|
+
writeFileSync4(join15(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
107358
107386
|
}
|
|
107359
107387
|
}
|
|
107360
107388
|
function createRenderJob(config2) {
|
|
@@ -107398,9 +107426,9 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
107398
107426
|
}
|
|
107399
107427
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
107400
107428
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
107401
|
-
const producerRoot = process.env.PRODUCER_RENDERS_DIR ?
|
|
107402
|
-
const debugDir =
|
|
107403
|
-
const workDir = job.config.debug ?
|
|
107429
|
+
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve10(process.env.PRODUCER_RENDERS_DIR, "..") : resolve10(moduleDir, "../..");
|
|
107430
|
+
const debugDir = join15(producerRoot, ".debug");
|
|
107431
|
+
const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
|
|
107404
107432
|
const pipelineStart = Date.now();
|
|
107405
107433
|
const log = job.config.logger ?? defaultLogger;
|
|
107406
107434
|
let fileServer = null;
|
|
@@ -107408,7 +107436,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107408
107436
|
let lastBrowserConsole = [];
|
|
107409
107437
|
let restoreLogger = null;
|
|
107410
107438
|
const perfStages = {};
|
|
107411
|
-
const perfOutputPath =
|
|
107439
|
+
const perfOutputPath = join15(workDir, "perf-summary.json");
|
|
107412
107440
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
107413
107441
|
const outputFormat = job.config.format ?? "mp4";
|
|
107414
107442
|
const isWebm = outputFormat === "webm";
|
|
@@ -107430,19 +107458,19 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107430
107458
|
assertNotAborted();
|
|
107431
107459
|
if (!existsSync15(workDir)) mkdirSync10(workDir, { recursive: true });
|
|
107432
107460
|
if (job.config.debug) {
|
|
107433
|
-
const logPath =
|
|
107461
|
+
const logPath = join15(workDir, "render.log");
|
|
107434
107462
|
restoreLogger = installDebugLogger(logPath, log);
|
|
107435
107463
|
}
|
|
107436
107464
|
const entryFile = job.config.entryFile || "index.html";
|
|
107437
|
-
let htmlPath =
|
|
107465
|
+
let htmlPath = join15(projectDir, entryFile);
|
|
107438
107466
|
if (!existsSync15(htmlPath)) {
|
|
107439
107467
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
107440
107468
|
}
|
|
107441
107469
|
assertNotAborted();
|
|
107442
107470
|
const rawEntry = readFileSync9(htmlPath, "utf-8");
|
|
107443
107471
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
107444
|
-
const wrapperPath =
|
|
107445
|
-
const projectIndexPath =
|
|
107472
|
+
const wrapperPath = join15(workDir, "standalone-entry.html");
|
|
107473
|
+
const projectIndexPath = join15(projectDir, "index.html");
|
|
107446
107474
|
if (!existsSync15(projectIndexPath)) {
|
|
107447
107475
|
throw new Error(
|
|
107448
107476
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
@@ -107466,7 +107494,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107466
107494
|
const stage1Start = Date.now();
|
|
107467
107495
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
107468
107496
|
const compileStart = Date.now();
|
|
107469
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
107497
|
+
let compiled = await compileForRender(projectDir, htmlPath, join15(workDir, "downloads"));
|
|
107470
107498
|
assertNotAborted();
|
|
107471
107499
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
107472
107500
|
writeCompiledArtifacts(compiled, workDir, Boolean(job.config.debug));
|
|
@@ -107495,7 +107523,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107495
107523
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
107496
107524
|
fileServer = await createFileServer2({
|
|
107497
107525
|
projectDir,
|
|
107498
|
-
compiledDir:
|
|
107526
|
+
compiledDir: join15(workDir, "compiled"),
|
|
107499
107527
|
port: 0
|
|
107500
107528
|
});
|
|
107501
107529
|
assertNotAborted();
|
|
@@ -107508,7 +107536,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107508
107536
|
};
|
|
107509
107537
|
probeSession = await createCaptureSession(
|
|
107510
107538
|
fileServer.url,
|
|
107511
|
-
|
|
107539
|
+
join15(workDir, "probe"),
|
|
107512
107540
|
captureOpts,
|
|
107513
107541
|
null,
|
|
107514
107542
|
cfg
|
|
@@ -107540,7 +107568,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107540
107568
|
compiled,
|
|
107541
107569
|
resolutions,
|
|
107542
107570
|
projectDir,
|
|
107543
|
-
|
|
107571
|
+
join15(workDir, "downloads")
|
|
107544
107572
|
);
|
|
107545
107573
|
assertNotAborted();
|
|
107546
107574
|
composition.videos = compiled.videos;
|
|
@@ -107675,12 +107703,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107675
107703
|
const stage2Start = Date.now();
|
|
107676
107704
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
107677
107705
|
let frameLookup = null;
|
|
107678
|
-
const compiledDir =
|
|
107706
|
+
const compiledDir = join15(workDir, "compiled");
|
|
107679
107707
|
if (composition.videos.length > 0) {
|
|
107680
107708
|
const extractionResult = await extractAllVideoFrames(
|
|
107681
107709
|
composition.videos,
|
|
107682
107710
|
projectDir,
|
|
107683
|
-
{ fps: job.config.fps, outputDir:
|
|
107711
|
+
{ fps: job.config.fps, outputDir: join15(workDir, "video-frames") },
|
|
107684
107712
|
abortSignal,
|
|
107685
107713
|
void 0,
|
|
107686
107714
|
compiledDir
|
|
@@ -107714,13 +107742,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107714
107742
|
}
|
|
107715
107743
|
const stage3Start = Date.now();
|
|
107716
107744
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
107717
|
-
const audioOutputPath =
|
|
107745
|
+
const audioOutputPath = join15(workDir, "audio.aac");
|
|
107718
107746
|
let hasAudio = false;
|
|
107719
107747
|
if (composition.audios.length > 0) {
|
|
107720
107748
|
const audioResult = await processCompositionAudio(
|
|
107721
107749
|
composition.audios,
|
|
107722
107750
|
projectDir,
|
|
107723
|
-
|
|
107751
|
+
join15(workDir, "audio-work"),
|
|
107724
107752
|
audioOutputPath,
|
|
107725
107753
|
job.duration,
|
|
107726
107754
|
abortSignal,
|
|
@@ -107738,12 +107766,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107738
107766
|
if (!fileServer) {
|
|
107739
107767
|
fileServer = await createFileServer2({
|
|
107740
107768
|
projectDir,
|
|
107741
|
-
compiledDir:
|
|
107769
|
+
compiledDir: join15(workDir, "compiled"),
|
|
107742
107770
|
port: 0
|
|
107743
107771
|
});
|
|
107744
107772
|
assertNotAborted();
|
|
107745
107773
|
}
|
|
107746
|
-
const framesDir =
|
|
107774
|
+
const framesDir = join15(workDir, "captured-frames");
|
|
107747
107775
|
if (!existsSync15(framesDir)) mkdirSync10(framesDir, { recursive: true });
|
|
107748
107776
|
const captureOptions = {
|
|
107749
107777
|
width,
|
|
@@ -107755,7 +107783,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
107755
107783
|
const workerCount = calculateOptimalWorkers(job.totalFrames, job.config.workers, cfg);
|
|
107756
107784
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
107757
107785
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
107758
|
-
const videoOnlyPath =
|
|
107786
|
+
const videoOnlyPath = join15(workDir, `video-only${videoExt}`);
|
|
107759
107787
|
const preset = getEncoderPreset(job.config.quality, outputFormat);
|
|
107760
107788
|
const effectiveQuality = job.config.crf ?? preset.quality;
|
|
107761
107789
|
const effectiveBitrate = job.config.videoBitrate;
|
|
@@ -108031,7 +108059,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
108031
108059
|
}
|
|
108032
108060
|
if (job.config.debug) {
|
|
108033
108061
|
if (existsSync15(outputPath)) {
|
|
108034
|
-
const debugOutput =
|
|
108062
|
+
const debugOutput = join15(workDir, `output${videoExt}`);
|
|
108035
108063
|
copyFileSync2(outputPath, debugOutput);
|
|
108036
108064
|
}
|
|
108037
108065
|
} else {
|
|
@@ -108290,7 +108318,7 @@ var streamSSE = (c, cb, onError) => {
|
|
|
108290
108318
|
|
|
108291
108319
|
// src/services/hyperframeLint.ts
|
|
108292
108320
|
import { existsSync as existsSync16, readFileSync as readFileSync10, statSync as statSync6 } from "node:fs";
|
|
108293
|
-
import { resolve as
|
|
108321
|
+
import { resolve as resolve11, join as join16 } from "node:path";
|
|
108294
108322
|
function isStringRecord(value) {
|
|
108295
108323
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
108296
108324
|
return false;
|
|
@@ -108317,7 +108345,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
108317
108345
|
return null;
|
|
108318
108346
|
}
|
|
108319
108347
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
108320
|
-
const absProjectDir =
|
|
108348
|
+
const absProjectDir = resolve11(projectDir);
|
|
108321
108349
|
if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
|
|
108322
108350
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
108323
108351
|
}
|
|
@@ -108325,7 +108353,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
108325
108353
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
108326
108354
|
);
|
|
108327
108355
|
for (const entryFile of entryCandidates) {
|
|
108328
|
-
const absoluteEntryPath =
|
|
108356
|
+
const absoluteEntryPath = resolve11(absProjectDir, entryFile);
|
|
108329
108357
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
108330
108358
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
108331
108359
|
}
|
|
@@ -108338,7 +108366,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
108338
108366
|
}
|
|
108339
108367
|
}
|
|
108340
108368
|
return {
|
|
108341
|
-
error: `No HTML entry file found in project directory: ${
|
|
108369
|
+
error: `No HTML entry file found in project directory: ${join16(absProjectDir, preferredEntryFile || "index.html")}`
|
|
108342
108370
|
};
|
|
108343
108371
|
}
|
|
108344
108372
|
function prepareHyperframeLintBody(body) {
|
|
@@ -108378,17 +108406,6 @@ function runHyperframeLint(prepared) {
|
|
|
108378
108406
|
return lintHyperframeHtml(prepared.html, { filePath: prepared.entryFile });
|
|
108379
108407
|
}
|
|
108380
108408
|
|
|
108381
|
-
// src/utils/paths.ts
|
|
108382
|
-
import { resolve as resolve11, basename as basename2, join as join16 } from "node:path";
|
|
108383
|
-
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve11(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108384
|
-
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108385
|
-
const absoluteProjectDir = resolve11(projectDir);
|
|
108386
|
-
const projectName = basename2(absoluteProjectDir);
|
|
108387
|
-
const resolvedOutputPath = outputPath ?? join16(rendersDir, `${projectName}.mp4`);
|
|
108388
|
-
const absoluteOutputPath = resolve11(resolvedOutputPath);
|
|
108389
|
-
return { absoluteProjectDir, absoluteOutputPath };
|
|
108390
|
-
}
|
|
108391
|
-
|
|
108392
108409
|
// src/utils/semaphore.ts
|
|
108393
108410
|
var Semaphore = class {
|
|
108394
108411
|
constructor(maxConcurrent) {
|