@hyperframes/producer 0.4.20 → 0.4.22
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 +819 -336
- package/dist/index.js.map +4 -4
- package/dist/public-server.js +819 -336
- package/dist/public-server.js.map +4 -4
- package/dist/services/hdrImageTransferCache.d.ts +17 -0
- package/dist/services/hdrImageTransferCache.d.ts.map +1 -0
- package/dist/services/htmlCompiler.d.ts.map +1 -1
- package/dist/services/renderOrchestrator.d.ts +14 -1
- package/dist/services/renderOrchestrator.d.ts.map +1 -1
- package/dist/services/videoFrameExtractor.d.ts +1 -1
- package/dist/services/videoFrameExtractor.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/public-server.js
CHANGED
|
@@ -7907,7 +7907,7 @@ function inertIfDisposed(target, _) {
|
|
|
7907
7907
|
};
|
|
7908
7908
|
}
|
|
7909
7909
|
function invokeAtMostOnceForArguments(target, _) {
|
|
7910
|
-
const
|
|
7910
|
+
const cache2 = /* @__PURE__ */ new WeakMap();
|
|
7911
7911
|
let cacheDepth = -1;
|
|
7912
7912
|
return function(...args) {
|
|
7913
7913
|
if (cacheDepth === -1) {
|
|
@@ -7917,7 +7917,7 @@ function invokeAtMostOnceForArguments(target, _) {
|
|
|
7917
7917
|
throw new Error("Memoized method was called with the wrong number of arguments");
|
|
7918
7918
|
}
|
|
7919
7919
|
let freshArguments = false;
|
|
7920
|
-
let cacheIterator =
|
|
7920
|
+
let cacheIterator = cache2;
|
|
7921
7921
|
for (const arg of args) {
|
|
7922
7922
|
if (cacheIterator.has(arg)) {
|
|
7923
7923
|
cacheIterator = cacheIterator.get(arg);
|
|
@@ -45140,7 +45140,7 @@ var require_websocket = __commonJS({
|
|
|
45140
45140
|
var http2 = __require("http");
|
|
45141
45141
|
var net = __require("net");
|
|
45142
45142
|
var tls = __require("tls");
|
|
45143
|
-
var { randomBytes, createHash:
|
|
45143
|
+
var { randomBytes, createHash: createHash4 } = __require("crypto");
|
|
45144
45144
|
var { Duplex, Readable: Readable3 } = __require("stream");
|
|
45145
45145
|
var { URL: URL3 } = __require("url");
|
|
45146
45146
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -45800,7 +45800,7 @@ var require_websocket = __commonJS({
|
|
|
45800
45800
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
45801
45801
|
return;
|
|
45802
45802
|
}
|
|
45803
|
-
const digest =
|
|
45803
|
+
const digest = createHash4("sha1").update(key2 + GUID).digest("base64");
|
|
45804
45804
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
45805
45805
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
45806
45806
|
return;
|
|
@@ -46167,7 +46167,7 @@ var require_websocket_server = __commonJS({
|
|
|
46167
46167
|
var EventEmitter4 = __require("events");
|
|
46168
46168
|
var http2 = __require("http");
|
|
46169
46169
|
var { Duplex } = __require("stream");
|
|
46170
|
-
var { createHash:
|
|
46170
|
+
var { createHash: createHash4 } = __require("crypto");
|
|
46171
46171
|
var extension = require_extension();
|
|
46172
46172
|
var PerMessageDeflate = require_permessage_deflate();
|
|
46173
46173
|
var subprotocol = require_subprotocol();
|
|
@@ -46468,7 +46468,7 @@ var require_websocket_server = __commonJS({
|
|
|
46468
46468
|
);
|
|
46469
46469
|
}
|
|
46470
46470
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
46471
|
-
const digest =
|
|
46471
|
+
const digest = createHash4("sha1").update(key2 + GUID).digest("base64");
|
|
46472
46472
|
const headers = [
|
|
46473
46473
|
"HTTP/1.1 101 Switching Protocols",
|
|
46474
46474
|
"Upgrade: websocket",
|
|
@@ -47604,7 +47604,7 @@ var require_range = __commonJS({
|
|
|
47604
47604
|
parseRange(range) {
|
|
47605
47605
|
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
|
|
47606
47606
|
const memoKey = memoOpts + ":" + range;
|
|
47607
|
-
const cached =
|
|
47607
|
+
const cached = cache2.get(memoKey);
|
|
47608
47608
|
if (cached) {
|
|
47609
47609
|
return cached;
|
|
47610
47610
|
}
|
|
@@ -47638,7 +47638,7 @@ var require_range = __commonJS({
|
|
|
47638
47638
|
rangeMap.delete("");
|
|
47639
47639
|
}
|
|
47640
47640
|
const result = [...rangeMap.values()];
|
|
47641
|
-
|
|
47641
|
+
cache2.set(memoKey, result);
|
|
47642
47642
|
return result;
|
|
47643
47643
|
}
|
|
47644
47644
|
intersects(range, options) {
|
|
@@ -47677,7 +47677,7 @@ var require_range = __commonJS({
|
|
|
47677
47677
|
};
|
|
47678
47678
|
module.exports = Range2;
|
|
47679
47679
|
var LRU = require_lrucache();
|
|
47680
|
-
var
|
|
47680
|
+
var cache2 = new LRU();
|
|
47681
47681
|
var parseOptions = require_parse_options();
|
|
47682
47682
|
var Comparator = require_comparator();
|
|
47683
47683
|
var debug6 = require_debug();
|
|
@@ -54357,12 +54357,12 @@ var require_data = __commonJS({
|
|
|
54357
54357
|
this.hash = hash2;
|
|
54358
54358
|
}
|
|
54359
54359
|
};
|
|
54360
|
-
var data = async ({ href: uri }, { cache } = {}) => {
|
|
54360
|
+
var data = async ({ href: uri }, { cache: cache2 } = {}) => {
|
|
54361
54361
|
const shasum = (0, crypto_1.createHash)("sha1");
|
|
54362
54362
|
shasum.update(uri);
|
|
54363
54363
|
const hash2 = shasum.digest("hex");
|
|
54364
54364
|
debug6('generated SHA1 hash for "data:" URI: %o', hash2);
|
|
54365
|
-
if (
|
|
54365
|
+
if (cache2?.hash === hash2) {
|
|
54366
54366
|
debug6("got matching cache SHA1 hash: %o", hash2);
|
|
54367
54367
|
throw new notmodified_1.default();
|
|
54368
54368
|
} else {
|
|
@@ -54407,7 +54407,7 @@ var require_file = __commonJS({
|
|
|
54407
54407
|
var debug6 = (0, debug_1.default)("get-uri:file");
|
|
54408
54408
|
var file = async ({ href: uri }, opts = {}) => {
|
|
54409
54409
|
const {
|
|
54410
|
-
cache,
|
|
54410
|
+
cache: cache2,
|
|
54411
54411
|
flags = "r",
|
|
54412
54412
|
mode = 438
|
|
54413
54413
|
// =0666
|
|
@@ -54418,7 +54418,7 @@ var require_file = __commonJS({
|
|
|
54418
54418
|
const fdHandle = await fs_1.promises.open(filepath, flags, mode);
|
|
54419
54419
|
const fd = fdHandle.fd;
|
|
54420
54420
|
const stat = await fdHandle.stat();
|
|
54421
|
-
if (
|
|
54421
|
+
if (cache2 && cache2.stat && stat && isNotModified(cache2.stat, stat)) {
|
|
54422
54422
|
await fdHandle.close();
|
|
54423
54423
|
throw new notmodified_1.default();
|
|
54424
54424
|
}
|
|
@@ -56438,7 +56438,7 @@ var require_ftp = __commonJS({
|
|
|
56438
56438
|
var notmodified_1 = __importDefault2(require_notmodified());
|
|
56439
56439
|
var debug6 = (0, debug_1.default)("get-uri:ftp");
|
|
56440
56440
|
var ftp = async (url, opts = {}) => {
|
|
56441
|
-
const { cache } = opts;
|
|
56441
|
+
const { cache: cache2 } = opts;
|
|
56442
56442
|
const filepath = decodeURIComponent(url.pathname);
|
|
56443
56443
|
let lastModified;
|
|
56444
56444
|
if (!filepath) {
|
|
@@ -56492,8 +56492,8 @@ var require_ftp = __commonJS({
|
|
|
56492
56492
|
throw err;
|
|
56493
56493
|
}
|
|
56494
56494
|
function isNotModified() {
|
|
56495
|
-
if (
|
|
56496
|
-
return +
|
|
56495
|
+
if (cache2?.lastModified && lastModified) {
|
|
56496
|
+
return +cache2.lastModified === +lastModified;
|
|
56497
56497
|
}
|
|
56498
56498
|
return false;
|
|
56499
56499
|
}
|
|
@@ -56538,10 +56538,10 @@ var require_http = __commonJS({
|
|
|
56538
56538
|
var debug6 = (0, debug_1.default)("get-uri:http");
|
|
56539
56539
|
var http2 = async (url, opts = {}) => {
|
|
56540
56540
|
debug6("GET %o", url.href);
|
|
56541
|
-
const
|
|
56542
|
-
if (
|
|
56543
|
-
const type2 =
|
|
56544
|
-
if (type2 === 3 &&
|
|
56541
|
+
const cache2 = getCache(url, opts.cache);
|
|
56542
|
+
if (cache2 && isFresh(cache2) && typeof cache2.statusCode === "number") {
|
|
56543
|
+
const type2 = cache2.statusCode / 100 | 0;
|
|
56544
|
+
if (type2 === 3 && cache2.headers.location) {
|
|
56545
56545
|
debug6("cached redirect");
|
|
56546
56546
|
throw new Error("TODO: implement cached redirects!");
|
|
56547
56547
|
}
|
|
@@ -56558,16 +56558,16 @@ var require_http = __commonJS({
|
|
|
56558
56558
|
debug6("using `http` core module");
|
|
56559
56559
|
}
|
|
56560
56560
|
const options = { ...opts };
|
|
56561
|
-
if (
|
|
56561
|
+
if (cache2) {
|
|
56562
56562
|
if (!options.headers) {
|
|
56563
56563
|
options.headers = {};
|
|
56564
56564
|
}
|
|
56565
|
-
const lastModified =
|
|
56565
|
+
const lastModified = cache2.headers["last-modified"];
|
|
56566
56566
|
if (lastModified) {
|
|
56567
56567
|
options.headers["If-Modified-Since"] = lastModified;
|
|
56568
56568
|
debug6('added "If-Modified-Since" request header: %o', lastModified);
|
|
56569
56569
|
}
|
|
56570
|
-
const etag =
|
|
56570
|
+
const etag = cache2.headers.etag;
|
|
56571
56571
|
if (etag) {
|
|
56572
56572
|
options.headers["If-None-Match"] = etag;
|
|
56573
56573
|
debug6('added "If-None-Match" request header: %o', etag);
|
|
@@ -56614,10 +56614,10 @@ var require_http = __commonJS({
|
|
|
56614
56614
|
return res;
|
|
56615
56615
|
};
|
|
56616
56616
|
exports.http = http2;
|
|
56617
|
-
function isFresh(
|
|
56617
|
+
function isFresh(cache2) {
|
|
56618
56618
|
let fresh = false;
|
|
56619
|
-
let expires = parseInt(
|
|
56620
|
-
const cacheControl =
|
|
56619
|
+
let expires = parseInt(cache2.headers.expires || "", 10);
|
|
56620
|
+
const cacheControl = cache2.headers["cache-control"];
|
|
56621
56621
|
if (cacheControl) {
|
|
56622
56622
|
debug6("Cache-Control: %o", cacheControl);
|
|
56623
56623
|
const parts = cacheControl.split(/,\s*?\b/);
|
|
@@ -56627,7 +56627,7 @@ var require_http = __commonJS({
|
|
|
56627
56627
|
const name = subparts[0];
|
|
56628
56628
|
switch (name) {
|
|
56629
56629
|
case "max-age":
|
|
56630
|
-
expires = (
|
|
56630
|
+
expires = (cache2.date || 0) + parseInt(subparts[1], 10) * 1e3;
|
|
56631
56631
|
fresh = Date.now() < expires;
|
|
56632
56632
|
if (fresh) {
|
|
56633
56633
|
debug6('cache is "fresh" due to previous %o Cache-Control param', part);
|
|
@@ -56653,14 +56653,14 @@ var require_http = __commonJS({
|
|
|
56653
56653
|
}
|
|
56654
56654
|
return false;
|
|
56655
56655
|
}
|
|
56656
|
-
function getCache(url,
|
|
56657
|
-
if (
|
|
56658
|
-
if (
|
|
56659
|
-
return
|
|
56656
|
+
function getCache(url, cache2) {
|
|
56657
|
+
if (cache2) {
|
|
56658
|
+
if (cache2.parsed && cache2.parsed.href === url.href) {
|
|
56659
|
+
return cache2;
|
|
56660
56660
|
}
|
|
56661
|
-
if (
|
|
56662
|
-
for (let i = 0; i <
|
|
56663
|
-
const c = getCache(url,
|
|
56661
|
+
if (cache2.redirects) {
|
|
56662
|
+
for (let i = 0; i < cache2.redirects.length; i++) {
|
|
56663
|
+
const c = getCache(url, cache2.redirects[i]);
|
|
56664
56664
|
if (c) {
|
|
56665
56665
|
return c;
|
|
56666
56666
|
}
|
|
@@ -57895,7 +57895,7 @@ var require_util2 = __commonJS({
|
|
|
57895
57895
|
return path12;
|
|
57896
57896
|
}
|
|
57897
57897
|
exports.normalize = normalize2;
|
|
57898
|
-
function
|
|
57898
|
+
function join19(aRoot, aPath) {
|
|
57899
57899
|
if (aRoot === "") {
|
|
57900
57900
|
aRoot = ".";
|
|
57901
57901
|
}
|
|
@@ -57927,7 +57927,7 @@ var require_util2 = __commonJS({
|
|
|
57927
57927
|
}
|
|
57928
57928
|
return joined;
|
|
57929
57929
|
}
|
|
57930
|
-
exports.join =
|
|
57930
|
+
exports.join = join19;
|
|
57931
57931
|
exports.isAbsolute = function(aPath) {
|
|
57932
57932
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
57933
57933
|
};
|
|
@@ -58100,7 +58100,7 @@ var require_util2 = __commonJS({
|
|
|
58100
58100
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
58101
58101
|
}
|
|
58102
58102
|
}
|
|
58103
|
-
sourceURL =
|
|
58103
|
+
sourceURL = join19(urlGenerate(parsed), sourceURL);
|
|
58104
58104
|
}
|
|
58105
58105
|
return normalize2(sourceURL);
|
|
58106
58106
|
}
|
|
@@ -59902,7 +59902,7 @@ var require_escodegen = __commonJS({
|
|
|
59902
59902
|
function noEmptySpace() {
|
|
59903
59903
|
return space ? space : " ";
|
|
59904
59904
|
}
|
|
59905
|
-
function
|
|
59905
|
+
function join19(left2, right2) {
|
|
59906
59906
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
59907
59907
|
leftSource = toSourceNodeWhenNeeded(left2).toString();
|
|
59908
59908
|
if (leftSource.length === 0) {
|
|
@@ -60233,8 +60233,8 @@ var require_escodegen = __commonJS({
|
|
|
60233
60233
|
} else {
|
|
60234
60234
|
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
60235
60235
|
}
|
|
60236
|
-
result =
|
|
60237
|
-
result = [
|
|
60236
|
+
result = join19(result, operator);
|
|
60237
|
+
result = [join19(
|
|
60238
60238
|
result,
|
|
60239
60239
|
that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)
|
|
60240
60240
|
), ")"];
|
|
@@ -60377,11 +60377,11 @@ var require_escodegen = __commonJS({
|
|
|
60377
60377
|
var result, fragment;
|
|
60378
60378
|
result = ["class"];
|
|
60379
60379
|
if (stmt.id) {
|
|
60380
|
-
result =
|
|
60380
|
+
result = join19(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
60381
60381
|
}
|
|
60382
60382
|
if (stmt.superClass) {
|
|
60383
|
-
fragment =
|
|
60384
|
-
result =
|
|
60383
|
+
fragment = join19("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
60384
|
+
result = join19(result, fragment);
|
|
60385
60385
|
}
|
|
60386
60386
|
result.push(space);
|
|
60387
60387
|
result.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -60394,9 +60394,9 @@ var require_escodegen = __commonJS({
|
|
|
60394
60394
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
60395
60395
|
},
|
|
60396
60396
|
DoWhileStatement: function(stmt, flags) {
|
|
60397
|
-
var result =
|
|
60397
|
+
var result = join19("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
60398
60398
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
60399
|
-
return
|
|
60399
|
+
return join19(result, [
|
|
60400
60400
|
"while" + space + "(",
|
|
60401
60401
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
60402
60402
|
")" + this.semicolon(flags)
|
|
@@ -60432,11 +60432,11 @@ var require_escodegen = __commonJS({
|
|
|
60432
60432
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
60433
60433
|
var result = ["export"], bodyFlags;
|
|
60434
60434
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60435
|
-
result =
|
|
60435
|
+
result = join19(result, "default");
|
|
60436
60436
|
if (isStatement(stmt.declaration)) {
|
|
60437
|
-
result =
|
|
60437
|
+
result = join19(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60438
60438
|
} else {
|
|
60439
|
-
result =
|
|
60439
|
+
result = join19(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
60440
60440
|
}
|
|
60441
60441
|
return result;
|
|
60442
60442
|
},
|
|
@@ -60444,15 +60444,15 @@ var require_escodegen = __commonJS({
|
|
|
60444
60444
|
var result = ["export"], bodyFlags, that = this;
|
|
60445
60445
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60446
60446
|
if (stmt.declaration) {
|
|
60447
|
-
return
|
|
60447
|
+
return join19(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60448
60448
|
}
|
|
60449
60449
|
if (stmt.specifiers) {
|
|
60450
60450
|
if (stmt.specifiers.length === 0) {
|
|
60451
|
-
result =
|
|
60451
|
+
result = join19(result, "{" + space + "}");
|
|
60452
60452
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
60453
|
-
result =
|
|
60453
|
+
result = join19(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
60454
60454
|
} else {
|
|
60455
|
-
result =
|
|
60455
|
+
result = join19(result, "{");
|
|
60456
60456
|
withIndent(function(indent2) {
|
|
60457
60457
|
var i, iz;
|
|
60458
60458
|
result.push(newline);
|
|
@@ -60470,7 +60470,7 @@ var require_escodegen = __commonJS({
|
|
|
60470
60470
|
result.push(base + "}");
|
|
60471
60471
|
}
|
|
60472
60472
|
if (stmt.source) {
|
|
60473
|
-
result =
|
|
60473
|
+
result = join19(result, [
|
|
60474
60474
|
"from" + space,
|
|
60475
60475
|
// ModuleSpecifier
|
|
60476
60476
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -60558,7 +60558,7 @@ var require_escodegen = __commonJS({
|
|
|
60558
60558
|
];
|
|
60559
60559
|
cursor = 0;
|
|
60560
60560
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
60561
|
-
result =
|
|
60561
|
+
result = join19(result, [
|
|
60562
60562
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60563
60563
|
]);
|
|
60564
60564
|
++cursor;
|
|
@@ -60568,7 +60568,7 @@ var require_escodegen = __commonJS({
|
|
|
60568
60568
|
result.push(",");
|
|
60569
60569
|
}
|
|
60570
60570
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
60571
|
-
result =
|
|
60571
|
+
result = join19(result, [
|
|
60572
60572
|
space,
|
|
60573
60573
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60574
60574
|
]);
|
|
@@ -60597,7 +60597,7 @@ var require_escodegen = __commonJS({
|
|
|
60597
60597
|
}
|
|
60598
60598
|
}
|
|
60599
60599
|
}
|
|
60600
|
-
result =
|
|
60600
|
+
result = join19(result, [
|
|
60601
60601
|
"from" + space,
|
|
60602
60602
|
// ModuleSpecifier
|
|
60603
60603
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -60651,7 +60651,7 @@ var require_escodegen = __commonJS({
|
|
|
60651
60651
|
return result;
|
|
60652
60652
|
},
|
|
60653
60653
|
ThrowStatement: function(stmt, flags) {
|
|
60654
|
-
return [
|
|
60654
|
+
return [join19(
|
|
60655
60655
|
"throw",
|
|
60656
60656
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
60657
60657
|
), this.semicolon(flags)];
|
|
@@ -60662,7 +60662,7 @@ var require_escodegen = __commonJS({
|
|
|
60662
60662
|
result = this.maybeBlockSuffix(stmt.block, result);
|
|
60663
60663
|
if (stmt.handlers) {
|
|
60664
60664
|
for (i = 0, iz = stmt.handlers.length; i < iz; ++i) {
|
|
60665
|
-
result =
|
|
60665
|
+
result = join19(result, this.generateStatement(stmt.handlers[i], S_TFFF));
|
|
60666
60666
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60667
60667
|
result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
|
|
60668
60668
|
}
|
|
@@ -60670,7 +60670,7 @@ var require_escodegen = __commonJS({
|
|
|
60670
60670
|
} else {
|
|
60671
60671
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
60672
60672
|
for (i = 0, iz = guardedHandlers.length; i < iz; ++i) {
|
|
60673
|
-
result =
|
|
60673
|
+
result = join19(result, this.generateStatement(guardedHandlers[i], S_TFFF));
|
|
60674
60674
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60675
60675
|
result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
|
|
60676
60676
|
}
|
|
@@ -60678,13 +60678,13 @@ var require_escodegen = __commonJS({
|
|
|
60678
60678
|
if (stmt.handler) {
|
|
60679
60679
|
if (Array.isArray(stmt.handler)) {
|
|
60680
60680
|
for (i = 0, iz = stmt.handler.length; i < iz; ++i) {
|
|
60681
|
-
result =
|
|
60681
|
+
result = join19(result, this.generateStatement(stmt.handler[i], S_TFFF));
|
|
60682
60682
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60683
60683
|
result = this.maybeBlockSuffix(stmt.handler[i].body, result);
|
|
60684
60684
|
}
|
|
60685
60685
|
}
|
|
60686
60686
|
} else {
|
|
60687
|
-
result =
|
|
60687
|
+
result = join19(result, this.generateStatement(stmt.handler, S_TFFF));
|
|
60688
60688
|
if (stmt.finalizer) {
|
|
60689
60689
|
result = this.maybeBlockSuffix(stmt.handler.body, result);
|
|
60690
60690
|
}
|
|
@@ -60692,7 +60692,7 @@ var require_escodegen = __commonJS({
|
|
|
60692
60692
|
}
|
|
60693
60693
|
}
|
|
60694
60694
|
if (stmt.finalizer) {
|
|
60695
|
-
result =
|
|
60695
|
+
result = join19(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
60696
60696
|
}
|
|
60697
60697
|
return result;
|
|
60698
60698
|
},
|
|
@@ -60726,7 +60726,7 @@ var require_escodegen = __commonJS({
|
|
|
60726
60726
|
withIndent(function() {
|
|
60727
60727
|
if (stmt.test) {
|
|
60728
60728
|
result = [
|
|
60729
|
-
|
|
60729
|
+
join19("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
60730
60730
|
":"
|
|
60731
60731
|
];
|
|
60732
60732
|
} else {
|
|
@@ -60774,9 +60774,9 @@ var require_escodegen = __commonJS({
|
|
|
60774
60774
|
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
60775
60775
|
result = this.maybeBlockSuffix(stmt.consequent, result);
|
|
60776
60776
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
60777
|
-
result =
|
|
60777
|
+
result = join19(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
60778
60778
|
} else {
|
|
60779
|
-
result =
|
|
60779
|
+
result = join19(result, join19("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
60780
60780
|
}
|
|
60781
60781
|
} else {
|
|
60782
60782
|
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -60877,7 +60877,7 @@ var require_escodegen = __commonJS({
|
|
|
60877
60877
|
},
|
|
60878
60878
|
ReturnStatement: function(stmt, flags) {
|
|
60879
60879
|
if (stmt.argument) {
|
|
60880
|
-
return [
|
|
60880
|
+
return [join19(
|
|
60881
60881
|
"return",
|
|
60882
60882
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
60883
60883
|
), this.semicolon(flags)];
|
|
@@ -60966,14 +60966,14 @@ var require_escodegen = __commonJS({
|
|
|
60966
60966
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
60967
60967
|
result = [fragment, noEmptySpace(), expr.operator];
|
|
60968
60968
|
} else {
|
|
60969
|
-
result =
|
|
60969
|
+
result = join19(fragment, expr.operator);
|
|
60970
60970
|
}
|
|
60971
60971
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
60972
60972
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
60973
60973
|
result.push(noEmptySpace());
|
|
60974
60974
|
result.push(fragment);
|
|
60975
60975
|
} else {
|
|
60976
|
-
result =
|
|
60976
|
+
result = join19(result, fragment);
|
|
60977
60977
|
}
|
|
60978
60978
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
60979
60979
|
return ["(", result, ")"];
|
|
@@ -61013,7 +61013,7 @@ var require_escodegen = __commonJS({
|
|
|
61013
61013
|
var result, length, i, iz, itemFlags;
|
|
61014
61014
|
length = expr["arguments"].length;
|
|
61015
61015
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
|
|
61016
|
-
result =
|
|
61016
|
+
result = join19(
|
|
61017
61017
|
"new",
|
|
61018
61018
|
this.generateExpression(expr.callee, Precedence.New, itemFlags)
|
|
61019
61019
|
);
|
|
@@ -61063,11 +61063,11 @@ var require_escodegen = __commonJS({
|
|
|
61063
61063
|
var result, fragment, rightCharCode, leftSource, leftCharCode;
|
|
61064
61064
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
61065
61065
|
if (space === "") {
|
|
61066
|
-
result =
|
|
61066
|
+
result = join19(expr.operator, fragment);
|
|
61067
61067
|
} else {
|
|
61068
61068
|
result = [expr.operator];
|
|
61069
61069
|
if (expr.operator.length > 2) {
|
|
61070
|
-
result =
|
|
61070
|
+
result = join19(result, fragment);
|
|
61071
61071
|
} else {
|
|
61072
61072
|
leftSource = toSourceNodeWhenNeeded(result).toString();
|
|
61073
61073
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -61090,7 +61090,7 @@ var require_escodegen = __commonJS({
|
|
|
61090
61090
|
result = "yield";
|
|
61091
61091
|
}
|
|
61092
61092
|
if (expr.argument) {
|
|
61093
|
-
result =
|
|
61093
|
+
result = join19(
|
|
61094
61094
|
result,
|
|
61095
61095
|
this.generateExpression(expr.argument, Precedence.Yield, E_TTT)
|
|
61096
61096
|
);
|
|
@@ -61098,7 +61098,7 @@ var require_escodegen = __commonJS({
|
|
|
61098
61098
|
return parenthesize(result, Precedence.Yield, precedence);
|
|
61099
61099
|
},
|
|
61100
61100
|
AwaitExpression: function(expr, precedence, flags) {
|
|
61101
|
-
var result =
|
|
61101
|
+
var result = join19(
|
|
61102
61102
|
expr.all ? "await*" : "await",
|
|
61103
61103
|
this.generateExpression(expr.argument, Precedence.Await, E_TTT)
|
|
61104
61104
|
);
|
|
@@ -61181,11 +61181,11 @@ var require_escodegen = __commonJS({
|
|
|
61181
61181
|
var result, fragment;
|
|
61182
61182
|
result = ["class"];
|
|
61183
61183
|
if (expr.id) {
|
|
61184
|
-
result =
|
|
61184
|
+
result = join19(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
61185
61185
|
}
|
|
61186
61186
|
if (expr.superClass) {
|
|
61187
|
-
fragment =
|
|
61188
|
-
result =
|
|
61187
|
+
fragment = join19("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
61188
|
+
result = join19(result, fragment);
|
|
61189
61189
|
}
|
|
61190
61190
|
result.push(space);
|
|
61191
61191
|
result.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -61200,7 +61200,7 @@ var require_escodegen = __commonJS({
|
|
|
61200
61200
|
}
|
|
61201
61201
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
61202
61202
|
fragment = [
|
|
61203
|
-
|
|
61203
|
+
join19(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
61204
61204
|
this.generateFunctionBody(expr.value)
|
|
61205
61205
|
];
|
|
61206
61206
|
} else {
|
|
@@ -61210,7 +61210,7 @@ var require_escodegen = __commonJS({
|
|
|
61210
61210
|
this.generateFunctionBody(expr.value)
|
|
61211
61211
|
];
|
|
61212
61212
|
}
|
|
61213
|
-
return
|
|
61213
|
+
return join19(result, fragment);
|
|
61214
61214
|
},
|
|
61215
61215
|
Property: function(expr, precedence, flags) {
|
|
61216
61216
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
@@ -61405,7 +61405,7 @@ var require_escodegen = __commonJS({
|
|
|
61405
61405
|
for (i = 0, iz = expr.blocks.length; i < iz; ++i) {
|
|
61406
61406
|
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
|
|
61407
61407
|
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61408
|
-
result =
|
|
61408
|
+
result = join19(result, fragment);
|
|
61409
61409
|
} else {
|
|
61410
61410
|
result.push(fragment);
|
|
61411
61411
|
}
|
|
@@ -61413,13 +61413,13 @@ var require_escodegen = __commonJS({
|
|
|
61413
61413
|
});
|
|
61414
61414
|
}
|
|
61415
61415
|
if (expr.filter) {
|
|
61416
|
-
result =
|
|
61416
|
+
result = join19(result, "if" + space);
|
|
61417
61417
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
61418
|
-
result =
|
|
61418
|
+
result = join19(result, ["(", fragment, ")"]);
|
|
61419
61419
|
}
|
|
61420
61420
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61421
61421
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
61422
|
-
result =
|
|
61422
|
+
result = join19(result, fragment);
|
|
61423
61423
|
}
|
|
61424
61424
|
result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
61425
61425
|
return result;
|
|
@@ -61435,8 +61435,8 @@ var require_escodegen = __commonJS({
|
|
|
61435
61435
|
} else {
|
|
61436
61436
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
61437
61437
|
}
|
|
61438
|
-
fragment =
|
|
61439
|
-
fragment =
|
|
61438
|
+
fragment = join19(fragment, expr.of ? "of" : "in");
|
|
61439
|
+
fragment = join19(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
61440
61440
|
return ["for" + space + "(", fragment, ")"];
|
|
61441
61441
|
},
|
|
61442
61442
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -69093,12 +69093,12 @@ var require_path = __commonJS({
|
|
|
69093
69093
|
return path12.__childCache || (path12.__childCache = /* @__PURE__ */ Object.create(null));
|
|
69094
69094
|
}
|
|
69095
69095
|
function getChildPath(path12, name) {
|
|
69096
|
-
var
|
|
69096
|
+
var cache2 = getChildCache(path12);
|
|
69097
69097
|
var actualChildValue = path12.getValueProperty(name);
|
|
69098
|
-
var childPath =
|
|
69099
|
-
if (!hasOwn.call(
|
|
69098
|
+
var childPath = cache2[name];
|
|
69099
|
+
if (!hasOwn.call(cache2, name) || // Ensure consistency between cache and reality.
|
|
69100
69100
|
childPath.value !== actualChildValue) {
|
|
69101
|
-
childPath =
|
|
69101
|
+
childPath = cache2[name] = new path12.constructor(actualChildValue, path12, name);
|
|
69102
69102
|
}
|
|
69103
69103
|
return childPath;
|
|
69104
69104
|
}
|
|
@@ -69174,7 +69174,7 @@ var require_path = __commonJS({
|
|
|
69174
69174
|
isNumber4.assert(start);
|
|
69175
69175
|
isNumber4.assert(end);
|
|
69176
69176
|
var moves = /* @__PURE__ */ Object.create(null);
|
|
69177
|
-
var
|
|
69177
|
+
var cache2 = getChildCache(path12);
|
|
69178
69178
|
for (var i = start; i < end; ++i) {
|
|
69179
69179
|
if (hasOwn.call(path12.value, i)) {
|
|
69180
69180
|
var childPath = path12.get(i);
|
|
@@ -69184,17 +69184,17 @@ var require_path = __commonJS({
|
|
|
69184
69184
|
var newIndex = i + offset;
|
|
69185
69185
|
childPath.name = newIndex;
|
|
69186
69186
|
moves[newIndex] = childPath;
|
|
69187
|
-
delete
|
|
69187
|
+
delete cache2[i];
|
|
69188
69188
|
}
|
|
69189
69189
|
}
|
|
69190
|
-
delete
|
|
69190
|
+
delete cache2.length;
|
|
69191
69191
|
return function() {
|
|
69192
69192
|
for (var newIndex2 in moves) {
|
|
69193
69193
|
var childPath2 = moves[newIndex2];
|
|
69194
69194
|
if (childPath2.name !== +newIndex2) {
|
|
69195
69195
|
throw new Error("");
|
|
69196
69196
|
}
|
|
69197
|
-
|
|
69197
|
+
cache2[newIndex2] = childPath2;
|
|
69198
69198
|
path12.value[newIndex2] = childPath2.value;
|
|
69199
69199
|
}
|
|
69200
69200
|
};
|
|
@@ -69226,9 +69226,9 @@ var require_path = __commonJS({
|
|
|
69226
69226
|
};
|
|
69227
69227
|
Pp.pop = function pop() {
|
|
69228
69228
|
isArray4.assert(this.value);
|
|
69229
|
-
var
|
|
69230
|
-
delete
|
|
69231
|
-
delete
|
|
69229
|
+
var cache2 = getChildCache(this);
|
|
69230
|
+
delete cache2[this.value.length - 1];
|
|
69231
|
+
delete cache2.length;
|
|
69232
69232
|
return this.value.pop();
|
|
69233
69233
|
};
|
|
69234
69234
|
Pp.insertAt = function insertAt(index) {
|
|
@@ -76740,12 +76740,12 @@ var init_Cache = __esm({
|
|
|
76740
76740
|
/**
|
|
76741
76741
|
* @internal
|
|
76742
76742
|
*/
|
|
76743
|
-
constructor(
|
|
76744
|
-
this.#cache =
|
|
76743
|
+
constructor(cache2, browser, buildId, platform) {
|
|
76744
|
+
this.#cache = cache2;
|
|
76745
76745
|
this.browser = browser;
|
|
76746
76746
|
this.buildId = buildId;
|
|
76747
76747
|
this.platform = platform;
|
|
76748
|
-
this.executablePath =
|
|
76748
|
+
this.executablePath = cache2.computeExecutablePath({
|
|
76749
76749
|
browser,
|
|
76750
76750
|
buildId,
|
|
76751
76751
|
platform
|
|
@@ -81915,8 +81915,8 @@ async function installWithProviders(options) {
|
|
|
81915
81915
|
if (!options.platform) {
|
|
81916
81916
|
throw new Error("Platform must be defined");
|
|
81917
81917
|
}
|
|
81918
|
-
const
|
|
81919
|
-
const browserRoot =
|
|
81918
|
+
const cache2 = new Cache(options.cacheDir);
|
|
81919
|
+
const browserRoot = cache2.browserRoot(options.browser);
|
|
81920
81920
|
const providers = [...options.providers || []];
|
|
81921
81921
|
if (options.baseUrl) {
|
|
81922
81922
|
providers.push(new DefaultProvider(options.baseUrl));
|
|
@@ -82018,8 +82018,8 @@ async function installUrl(url, options, provider) {
|
|
|
82018
82018
|
}
|
|
82019
82019
|
const fileName = decodeURIComponent(url.toString()).split("/").pop();
|
|
82020
82020
|
assert2(fileName, `A malformed download URL was found: ${url}.`);
|
|
82021
|
-
const
|
|
82022
|
-
const browserRoot =
|
|
82021
|
+
const cache2 = new Cache(options.cacheDir);
|
|
82022
|
+
const browserRoot = cache2.browserRoot(options.browser);
|
|
82023
82023
|
const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
|
|
82024
82024
|
if (!existsSync(browserRoot)) {
|
|
82025
82025
|
await mkdir2(browserRoot, { recursive: true });
|
|
@@ -82034,16 +82034,16 @@ async function installUrl(url, options, provider) {
|
|
|
82034
82034
|
debugTimeEnd("download");
|
|
82035
82035
|
return archivePath;
|
|
82036
82036
|
}
|
|
82037
|
-
const outputPath =
|
|
82037
|
+
const outputPath = cache2.installationDir(options.browser, options.platform, options.buildId);
|
|
82038
82038
|
const relativeExecutablePath6 = await provider.getExecutablePath({
|
|
82039
82039
|
browser: options.browser,
|
|
82040
82040
|
buildId: options.buildId,
|
|
82041
82041
|
platform: options.platform
|
|
82042
82042
|
});
|
|
82043
82043
|
debugInstall(`Using executable path from provider: ${relativeExecutablePath6}`);
|
|
82044
|
-
const installedBrowser = new InstalledBrowser(
|
|
82044
|
+
const installedBrowser = new InstalledBrowser(cache2, options.browser, options.buildId, options.platform);
|
|
82045
82045
|
if (!(provider instanceof DefaultProvider)) {
|
|
82046
|
-
|
|
82046
|
+
cache2.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
|
|
82047
82047
|
}
|
|
82048
82048
|
try {
|
|
82049
82049
|
if (existsSync(outputPath)) {
|
|
@@ -87415,8 +87415,8 @@ var init_CLI = __esm({
|
|
|
87415
87415
|
console.log("Cancelled.");
|
|
87416
87416
|
return;
|
|
87417
87417
|
}
|
|
87418
|
-
const
|
|
87419
|
-
|
|
87418
|
+
const cache2 = new Cache(cacheDir);
|
|
87419
|
+
cache2.clear();
|
|
87420
87420
|
console.log(`${cacheDir} cleared.`);
|
|
87421
87421
|
});
|
|
87422
87422
|
}).command("list", "List all installed browsers in the cache directory", (yargs2) => {
|
|
@@ -87427,8 +87427,8 @@ var init_CLI = __esm({
|
|
|
87427
87427
|
return this.#definePathParameter(yargs2);
|
|
87428
87428
|
}, async (args) => {
|
|
87429
87429
|
const cacheDir = args.path ?? this.#cachePath;
|
|
87430
|
-
const
|
|
87431
|
-
const browsers =
|
|
87430
|
+
const cache2 = new Cache(cacheDir);
|
|
87431
|
+
const browsers = cache2.getInstalledBrowsers();
|
|
87432
87432
|
for (const browser of browsers) {
|
|
87433
87433
|
console.log(`${browser.browser}@${browser.buildId} (${browser.platform}) ${browser.executablePath}`);
|
|
87434
87434
|
}
|
|
@@ -87598,9 +87598,9 @@ async function getConnectionTransport(options) {
|
|
|
87598
87598
|
throw new Error("Could not detect required browser platform");
|
|
87599
87599
|
}
|
|
87600
87600
|
const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), LaunchOptions_exports));
|
|
87601
|
-
const { join:
|
|
87601
|
+
const { join: join19 } = await import("node:path");
|
|
87602
87602
|
const userDataDir = resolveDefaultUserDataDir3(Browser4.CHROME, platform, convertPuppeteerChannelToBrowsersChannel2(options.channel));
|
|
87603
|
-
const portPath =
|
|
87603
|
+
const portPath = join19(userDataDir, "DevToolsActivePort");
|
|
87604
87604
|
try {
|
|
87605
87605
|
const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
|
|
87606
87606
|
const [rawPort, rawPath] = fileContent.split("\n").map((line) => {
|
|
@@ -89418,15 +89418,15 @@ var init_puppeteer_core = __esm({
|
|
|
89418
89418
|
|
|
89419
89419
|
// src/server.ts
|
|
89420
89420
|
import {
|
|
89421
|
-
existsSync as
|
|
89422
|
-
mkdirSync as
|
|
89423
|
-
statSync as
|
|
89421
|
+
existsSync as existsSync18,
|
|
89422
|
+
mkdirSync as mkdirSync12,
|
|
89423
|
+
statSync as statSync9,
|
|
89424
89424
|
mkdtempSync,
|
|
89425
|
-
writeFileSync as
|
|
89425
|
+
writeFileSync as writeFileSync6,
|
|
89426
89426
|
rmSync as rmSync4,
|
|
89427
89427
|
createReadStream as createReadStream2
|
|
89428
89428
|
} from "node:fs";
|
|
89429
|
-
import { resolve as resolve13, dirname as dirname11, join as
|
|
89429
|
+
import { resolve as resolve13, dirname as dirname11, join as join18 } from "node:path";
|
|
89430
89430
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
89431
89431
|
import { parseArgs } from "node:util";
|
|
89432
89432
|
import crypto2 from "node:crypto";
|
|
@@ -91854,14 +91854,14 @@ var Response2 = class _Response {
|
|
|
91854
91854
|
}
|
|
91855
91855
|
}
|
|
91856
91856
|
get headers() {
|
|
91857
|
-
const
|
|
91858
|
-
if (
|
|
91859
|
-
if (!(
|
|
91860
|
-
|
|
91861
|
-
|
|
91857
|
+
const cache2 = this[cacheKey];
|
|
91858
|
+
if (cache2) {
|
|
91859
|
+
if (!(cache2[2] instanceof Headers)) {
|
|
91860
|
+
cache2[2] = new Headers(
|
|
91861
|
+
cache2[2] || { "content-type": "text/plain; charset=UTF-8" }
|
|
91862
91862
|
);
|
|
91863
91863
|
}
|
|
91864
|
-
return
|
|
91864
|
+
return cache2[2];
|
|
91865
91865
|
}
|
|
91866
91866
|
return this[getResponseCache]().headers;
|
|
91867
91867
|
}
|
|
@@ -92206,12 +92206,13 @@ var serve = (options, listeningListener) => {
|
|
|
92206
92206
|
|
|
92207
92207
|
// src/services/renderOrchestrator.ts
|
|
92208
92208
|
import {
|
|
92209
|
-
existsSync as
|
|
92210
|
-
mkdirSync as
|
|
92209
|
+
existsSync as existsSync16,
|
|
92210
|
+
mkdirSync as mkdirSync11,
|
|
92211
92211
|
rmSync as rmSync3,
|
|
92212
92212
|
readFileSync as readFileSync10,
|
|
92213
|
-
readdirSync as
|
|
92214
|
-
|
|
92213
|
+
readdirSync as readdirSync8,
|
|
92214
|
+
statSync as statSync7,
|
|
92215
|
+
writeFileSync as writeFileSync5,
|
|
92215
92216
|
copyFileSync as copyFileSync2,
|
|
92216
92217
|
appendFileSync
|
|
92217
92218
|
} from "fs";
|
|
@@ -101536,7 +101537,8 @@ function resolveConfig(overrides) {
|
|
|
101536
101537
|
DEFAULT_CONFIG.renderReadyTimeout
|
|
101537
101538
|
),
|
|
101538
101539
|
verifyRuntime: env2("PRODUCER_VERIFY_HYPERFRAME_RUNTIME") !== "false",
|
|
101539
|
-
runtimeManifestPath: env2("PRODUCER_HYPERFRAME_MANIFEST_PATH")
|
|
101540
|
+
runtimeManifestPath: env2("PRODUCER_HYPERFRAME_MANIFEST_PATH"),
|
|
101541
|
+
extractCacheDir: env2("HYPERFRAMES_EXTRACT_CACHE_DIR")
|
|
101540
101542
|
};
|
|
101541
101543
|
const cleanEnv = Object.fromEntries(Object.entries(fromEnv).filter(([, v]) => v !== void 0));
|
|
101542
101544
|
return {
|
|
@@ -102692,6 +102694,7 @@ var mediaRules = [
|
|
|
102692
102694
|
|
|
102693
102695
|
// ../core/src/lint/rules/gsap.ts
|
|
102694
102696
|
var META_GSAP_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "repeat", "yoyo", "overwrite", "delay"]);
|
|
102697
|
+
var SCENE_BOUNDARY_EPSILON_SECONDS = 0.05;
|
|
102695
102698
|
function countClassUsage(tags) {
|
|
102696
102699
|
const counts = /* @__PURE__ */ new Map();
|
|
102697
102700
|
for (const tag of tags) {
|
|
@@ -102732,6 +102735,7 @@ function extractGsapWindows(script) {
|
|
|
102732
102735
|
position: animation.position,
|
|
102733
102736
|
end: animation.position + meta.effectiveDuration,
|
|
102734
102737
|
properties: meta.properties.length > 0 ? meta.properties : Object.keys(animation.properties),
|
|
102738
|
+
propertyValues: meta.propertyValues,
|
|
102735
102739
|
overwriteAuto: meta.overwriteAuto,
|
|
102736
102740
|
method: match2[1] ?? "to",
|
|
102737
102741
|
raw: raw2
|
|
@@ -102740,8 +102744,14 @@ function extractGsapWindows(script) {
|
|
|
102740
102744
|
return windows;
|
|
102741
102745
|
}
|
|
102742
102746
|
function parseGsapWindowMeta(method, argsStr) {
|
|
102747
|
+
const emptyMeta = {
|
|
102748
|
+
effectiveDuration: 0,
|
|
102749
|
+
properties: [],
|
|
102750
|
+
propertyValues: {},
|
|
102751
|
+
overwriteAuto: false
|
|
102752
|
+
};
|
|
102743
102753
|
const selectorMatch = argsStr.match(/^\s*["']([^"']+)["']\s*,/);
|
|
102744
|
-
if (!selectorMatch) return
|
|
102754
|
+
if (!selectorMatch) return emptyMeta;
|
|
102745
102755
|
const afterSelector = argsStr.slice(selectorMatch[0].length);
|
|
102746
102756
|
let properties = {};
|
|
102747
102757
|
let fromProperties = {};
|
|
@@ -102779,6 +102789,7 @@ function parseGsapWindowMeta(method, argsStr) {
|
|
|
102779
102789
|
return {
|
|
102780
102790
|
effectiveDuration: method === "set" ? 0 : effectiveDuration,
|
|
102781
102791
|
properties: [...propertyNames],
|
|
102792
|
+
propertyValues: properties,
|
|
102782
102793
|
overwriteAuto
|
|
102783
102794
|
};
|
|
102784
102795
|
}
|
|
@@ -102826,6 +102837,94 @@ function stringValue(value) {
|
|
|
102826
102837
|
if (typeof value === "number") return String(value);
|
|
102827
102838
|
return null;
|
|
102828
102839
|
}
|
|
102840
|
+
function zeroValue(value) {
|
|
102841
|
+
if (typeof value === "number") return value === 0;
|
|
102842
|
+
if (typeof value !== "string") return false;
|
|
102843
|
+
return Number(value.trim()) === 0;
|
|
102844
|
+
}
|
|
102845
|
+
function isHiddenGsapState(values) {
|
|
102846
|
+
const visibility = stringValue(values.visibility)?.toLowerCase();
|
|
102847
|
+
const display = stringValue(values.display)?.toLowerCase();
|
|
102848
|
+
return zeroValue(values.opacity) || zeroValue(values.autoAlpha) || visibility === "hidden" || display === "none";
|
|
102849
|
+
}
|
|
102850
|
+
function isSceneBoundaryExit(win) {
|
|
102851
|
+
if (win.end <= win.position) return false;
|
|
102852
|
+
if (win.method !== "to" && win.method !== "fromTo") return false;
|
|
102853
|
+
return isHiddenGsapState(win.propertyValues);
|
|
102854
|
+
}
|
|
102855
|
+
function isHardKillSet(win, selector, boundary) {
|
|
102856
|
+
return win.method === "set" && win.targetSelector === selector && Math.abs(win.position - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS && isHiddenGsapState(win.propertyValues);
|
|
102857
|
+
}
|
|
102858
|
+
function hiddenStateLiteral(values) {
|
|
102859
|
+
if (zeroValue(values.autoAlpha)) return "{ autoAlpha: 0 }";
|
|
102860
|
+
if (zeroValue(values.opacity)) return "{ opacity: 0 }";
|
|
102861
|
+
if (stringValue(values.visibility)?.toLowerCase() === "hidden") return '{ visibility: "hidden" }';
|
|
102862
|
+
if (stringValue(values.display)?.toLowerCase() === "none") return '{ display: "none" }';
|
|
102863
|
+
return "{ opacity: 0 }";
|
|
102864
|
+
}
|
|
102865
|
+
function findTagEnd(source2, tag) {
|
|
102866
|
+
const escapedTagName = tag.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
102867
|
+
const pattern = new RegExp(`<\\/?${escapedTagName}\\b[^>]*>`, "gi");
|
|
102868
|
+
pattern.lastIndex = tag.index;
|
|
102869
|
+
let depth = 0;
|
|
102870
|
+
let match2;
|
|
102871
|
+
while ((match2 = pattern.exec(source2)) !== null) {
|
|
102872
|
+
const raw2 = match2[0];
|
|
102873
|
+
const isClosing = /^<\s*\//.test(raw2);
|
|
102874
|
+
const isSelfClosing = /\/\s*>$/.test(raw2);
|
|
102875
|
+
if (!isClosing && !isSelfClosing) depth += 1;
|
|
102876
|
+
if (isClosing) depth -= 1;
|
|
102877
|
+
if (depth === 0) return pattern.lastIndex;
|
|
102878
|
+
}
|
|
102879
|
+
return source2.length;
|
|
102880
|
+
}
|
|
102881
|
+
function collectCompositionRanges(source2, tags) {
|
|
102882
|
+
return tags.map((tag) => {
|
|
102883
|
+
const id = readAttr(tag.raw, "data-composition-id");
|
|
102884
|
+
if (!id) return null;
|
|
102885
|
+
return {
|
|
102886
|
+
id,
|
|
102887
|
+
start: tag.index,
|
|
102888
|
+
end: findTagEnd(source2, tag)
|
|
102889
|
+
};
|
|
102890
|
+
}).filter((range) => range !== null);
|
|
102891
|
+
}
|
|
102892
|
+
function findContainingCompositionId(tag, ranges) {
|
|
102893
|
+
let match2 = null;
|
|
102894
|
+
for (const range of ranges) {
|
|
102895
|
+
if (tag.index < range.start || tag.index >= range.end) continue;
|
|
102896
|
+
if (!match2 || range.start >= match2.start) match2 = range;
|
|
102897
|
+
}
|
|
102898
|
+
return match2?.id || null;
|
|
102899
|
+
}
|
|
102900
|
+
function collectClipStartBoundariesByComposition(source2, tags) {
|
|
102901
|
+
const ranges = collectCompositionRanges(source2, tags);
|
|
102902
|
+
const boundaries = /* @__PURE__ */ new Map();
|
|
102903
|
+
for (const tag of tags) {
|
|
102904
|
+
const classAttr = readAttr(tag.raw, "class") || "";
|
|
102905
|
+
const classes = classAttr.split(/\s+/).filter(Boolean);
|
|
102906
|
+
if (!classes.includes("clip")) continue;
|
|
102907
|
+
const compositionId = findContainingCompositionId(tag, ranges);
|
|
102908
|
+
if (!compositionId) continue;
|
|
102909
|
+
const start = numberValue(readAttr(tag.raw, "data-start") ?? void 0);
|
|
102910
|
+
if (start == null || start <= 0) continue;
|
|
102911
|
+
const compositionBoundaries = boundaries.get(compositionId) ?? /* @__PURE__ */ new Set();
|
|
102912
|
+
compositionBoundaries.add(start);
|
|
102913
|
+
boundaries.set(compositionId, compositionBoundaries);
|
|
102914
|
+
}
|
|
102915
|
+
return new Map(
|
|
102916
|
+
[...boundaries.entries()].map(([compositionId, values]) => [
|
|
102917
|
+
compositionId,
|
|
102918
|
+
[...values].sort((a, b) => a - b)
|
|
102919
|
+
])
|
|
102920
|
+
);
|
|
102921
|
+
}
|
|
102922
|
+
function findMatchingSceneBoundary(time, boundaries) {
|
|
102923
|
+
for (const boundary of boundaries) {
|
|
102924
|
+
if (Math.abs(time - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS) return boundary;
|
|
102925
|
+
}
|
|
102926
|
+
return null;
|
|
102927
|
+
}
|
|
102829
102928
|
function isSuspiciousGlobalSelector(selector) {
|
|
102830
102929
|
if (!selector) return false;
|
|
102831
102930
|
if (selector.includes("[data-composition-id=")) return false;
|
|
@@ -102866,7 +102965,7 @@ function cssTransformToGsapProps(cssTransform) {
|
|
|
102866
102965
|
}
|
|
102867
102966
|
var gsapRules = [
|
|
102868
102967
|
// overlapping_gsap_tweens + gsap_animates_clip_element + unscoped_gsap_selector
|
|
102869
|
-
({ tags, scripts, rootCompositionId }) => {
|
|
102968
|
+
({ source: source2, tags, scripts, rootCompositionId }) => {
|
|
102870
102969
|
const findings = [];
|
|
102871
102970
|
const clipIds = /* @__PURE__ */ new Map();
|
|
102872
102971
|
const clipClasses = /* @__PURE__ */ new Map();
|
|
@@ -102886,9 +102985,11 @@ var gsapRules = [
|
|
|
102886
102985
|
}
|
|
102887
102986
|
}
|
|
102888
102987
|
const classUsage = countClassUsage(tags);
|
|
102988
|
+
const clipStartBoundariesByComposition = collectClipStartBoundariesByComposition(source2, tags);
|
|
102889
102989
|
for (const script of scripts) {
|
|
102890
102990
|
const localTimelineCompId = readRegisteredTimelineCompositionId(script.content);
|
|
102891
102991
|
const gsapWindows = extractGsapWindows(script.content);
|
|
102992
|
+
const clipStartBoundaries = clipStartBoundariesByComposition.get(localTimelineCompId || rootCompositionId || "") ?? [];
|
|
102892
102993
|
for (let i = 0; i < gsapWindows.length; i++) {
|
|
102893
102994
|
const left2 = gsapWindows[i];
|
|
102894
102995
|
if (!left2) continue;
|
|
@@ -102917,6 +103018,25 @@ ${right2.raw}`)
|
|
|
102917
103018
|
});
|
|
102918
103019
|
}
|
|
102919
103020
|
}
|
|
103021
|
+
if (clipStartBoundaries.length > 0) {
|
|
103022
|
+
for (const win of gsapWindows) {
|
|
103023
|
+
if (!isSceneBoundaryExit(win)) continue;
|
|
103024
|
+
const boundary = findMatchingSceneBoundary(win.end, clipStartBoundaries);
|
|
103025
|
+
if (boundary == null) continue;
|
|
103026
|
+
const hasHardKill = gsapWindows.some(
|
|
103027
|
+
(candidate) => isHardKillSet(candidate, win.targetSelector, boundary)
|
|
103028
|
+
);
|
|
103029
|
+
if (hasHardKill) continue;
|
|
103030
|
+
findings.push({
|
|
103031
|
+
code: "gsap_exit_missing_hard_kill",
|
|
103032
|
+
severity: "warning",
|
|
103033
|
+
message: `GSAP exit on "${win.targetSelector}" ends at the ${boundary.toFixed(2)}s clip start boundary without a matching tl.set hard kill. Non-linear seeking can land after the fade and leave stale visibility state.`,
|
|
103034
|
+
selector: win.targetSelector,
|
|
103035
|
+
fixHint: `Add \`tl.set("${win.targetSelector}", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\` after the exit tween.`,
|
|
103036
|
+
snippet: truncateSnippet(win.raw)
|
|
103037
|
+
});
|
|
103038
|
+
}
|
|
103039
|
+
}
|
|
102920
103040
|
for (const win of gsapWindows) {
|
|
102921
103041
|
const sel = win.targetSelector;
|
|
102922
103042
|
const clipInfo = clipIds.get(sel) || clipClasses.get(sel);
|
|
@@ -105231,8 +105351,8 @@ Process error: ${err.message}`;
|
|
|
105231
105351
|
|
|
105232
105352
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
105233
105353
|
import { spawn as spawn8 } from "child_process";
|
|
105234
|
-
import { existsSync as
|
|
105235
|
-
import { isAbsolute as isAbsolute2, join as
|
|
105354
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync5, rmSync } from "fs";
|
|
105355
|
+
import { isAbsolute as isAbsolute2, join as join9 } from "path";
|
|
105236
105356
|
|
|
105237
105357
|
// ../engine/src/utils/ffprobe.ts
|
|
105238
105358
|
import { spawn as spawn7 } from "child_process";
|
|
@@ -105562,10 +105682,115 @@ function isHttpUrl(path12) {
|
|
|
105562
105682
|
return path12.startsWith("http://") || path12.startsWith("https://");
|
|
105563
105683
|
}
|
|
105564
105684
|
|
|
105685
|
+
// ../engine/src/utils/htmlTemplate.ts
|
|
105686
|
+
function parseHTMLContent(html) {
|
|
105687
|
+
const trimmed = html.trimStart().toLowerCase();
|
|
105688
|
+
if (trimmed.startsWith("<!doctype") || trimmed.startsWith("<html")) {
|
|
105689
|
+
return parseHTML(html).document;
|
|
105690
|
+
}
|
|
105691
|
+
return parseHTML(`<!DOCTYPE html><html><head></head><body>${html}</body></html>`).document;
|
|
105692
|
+
}
|
|
105693
|
+
function getSingleMeaningfulChild(container) {
|
|
105694
|
+
let child = null;
|
|
105695
|
+
for (const node of Array.from(container.childNodes)) {
|
|
105696
|
+
if (node.nodeType === 3 && !(node.textContent || "").trim()) continue;
|
|
105697
|
+
if (node.nodeType === 8) continue;
|
|
105698
|
+
if (node.nodeType !== 1) return null;
|
|
105699
|
+
if (child) return null;
|
|
105700
|
+
child = node;
|
|
105701
|
+
}
|
|
105702
|
+
return child;
|
|
105703
|
+
}
|
|
105704
|
+
function unwrapTemplate(html) {
|
|
105705
|
+
const lowered = html.toLowerCase();
|
|
105706
|
+
if (!lowered.includes("<template") || !lowered.includes("</template>")) {
|
|
105707
|
+
return html;
|
|
105708
|
+
}
|
|
105709
|
+
const { body } = parseHTMLContent(html);
|
|
105710
|
+
if (!body) return html;
|
|
105711
|
+
let container = body;
|
|
105712
|
+
const bodyWrapper = getSingleMeaningfulChild(container);
|
|
105713
|
+
if (bodyWrapper?.tagName === "BODY") {
|
|
105714
|
+
container = bodyWrapper;
|
|
105715
|
+
}
|
|
105716
|
+
const template = getSingleMeaningfulChild(container);
|
|
105717
|
+
if (template?.tagName !== "TEMPLATE") {
|
|
105718
|
+
return html;
|
|
105719
|
+
}
|
|
105720
|
+
return template.innerHTML ?? html;
|
|
105721
|
+
}
|
|
105722
|
+
|
|
105723
|
+
// ../engine/src/services/extractionCache.ts
|
|
105724
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
105725
|
+
import { mkdirSync as mkdirSync5, readdirSync as readdirSync4, statSync as statSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
105726
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
105727
|
+
import { join as join8 } from "node:path";
|
|
105728
|
+
var FRAME_FILENAME_PREFIX = "frame_";
|
|
105729
|
+
var COMPLETE_SENTINEL = ".hf-complete";
|
|
105730
|
+
var SCHEMA_PREFIX = "hfcache-v2-";
|
|
105731
|
+
var KEY_HEX_CHARS = 16;
|
|
105732
|
+
function readKeyStat(videoPath) {
|
|
105733
|
+
try {
|
|
105734
|
+
const stat = statSync5(videoPath);
|
|
105735
|
+
return { mtimeMs: Math.floor(stat.mtimeMs), size: stat.size };
|
|
105736
|
+
} catch {
|
|
105737
|
+
return null;
|
|
105738
|
+
}
|
|
105739
|
+
}
|
|
105740
|
+
function canonicalKeyBlob(input2) {
|
|
105741
|
+
const durationForKey = Number.isFinite(input2.duration) ? input2.duration : -1;
|
|
105742
|
+
return JSON.stringify({
|
|
105743
|
+
p: input2.videoPath,
|
|
105744
|
+
m: input2.mtimeMs,
|
|
105745
|
+
s: input2.size,
|
|
105746
|
+
ms: input2.mediaStart,
|
|
105747
|
+
d: durationForKey,
|
|
105748
|
+
f: input2.fps,
|
|
105749
|
+
fmt: input2.format
|
|
105750
|
+
});
|
|
105751
|
+
}
|
|
105752
|
+
function computeCacheKey(input2) {
|
|
105753
|
+
return createHash2("sha256").update(canonicalKeyBlob(input2)).digest("hex");
|
|
105754
|
+
}
|
|
105755
|
+
function cacheEntryDirName(keyHash) {
|
|
105756
|
+
return SCHEMA_PREFIX + keyHash.slice(0, KEY_HEX_CHARS);
|
|
105757
|
+
}
|
|
105758
|
+
function lookupCacheEntry(rootDir, input2) {
|
|
105759
|
+
const keyHash = computeCacheKey(input2);
|
|
105760
|
+
const dir = join8(rootDir, cacheEntryDirName(keyHash));
|
|
105761
|
+
const complete = existsSync8(join8(dir, COMPLETE_SENTINEL));
|
|
105762
|
+
return { entry: { dir, keyHash }, hit: complete };
|
|
105763
|
+
}
|
|
105764
|
+
function ensureCacheEntryDir(entry) {
|
|
105765
|
+
mkdirSync5(entry.dir, { recursive: true });
|
|
105766
|
+
}
|
|
105767
|
+
function markCacheEntryComplete(entry) {
|
|
105768
|
+
writeFileSync3(join8(entry.dir, COMPLETE_SENTINEL), "", "utf-8");
|
|
105769
|
+
}
|
|
105770
|
+
function rehydrateCacheEntry(entry, options) {
|
|
105771
|
+
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
105772
|
+
const framePaths = /* @__PURE__ */ new Map();
|
|
105773
|
+
const suffix = `.${options.format}`;
|
|
105774
|
+
const files = readdirSync4(entry.dir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(suffix)).sort();
|
|
105775
|
+
files.forEach((file, idx) => {
|
|
105776
|
+
framePaths.set(idx, join8(entry.dir, file));
|
|
105777
|
+
});
|
|
105778
|
+
return {
|
|
105779
|
+
videoId: options.videoId,
|
|
105780
|
+
srcPath: options.srcPath,
|
|
105781
|
+
outputDir: entry.dir,
|
|
105782
|
+
framePattern,
|
|
105783
|
+
fps: options.fps,
|
|
105784
|
+
totalFrames: framePaths.size,
|
|
105785
|
+
metadata: options.metadata,
|
|
105786
|
+
framePaths
|
|
105787
|
+
};
|
|
105788
|
+
}
|
|
105789
|
+
|
|
105565
105790
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
105566
105791
|
function parseVideoElements(html) {
|
|
105567
105792
|
const videos = [];
|
|
105568
|
-
const { document: document2 } = parseHTML(html);
|
|
105793
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
105569
105794
|
const videoEls = document2.querySelectorAll("video[src]");
|
|
105570
105795
|
let autoIdCounter = 0;
|
|
105571
105796
|
for (const el of videoEls) {
|
|
@@ -105602,7 +105827,7 @@ function parseVideoElements(html) {
|
|
|
105602
105827
|
}
|
|
105603
105828
|
function parseImageElements(html) {
|
|
105604
105829
|
const images = [];
|
|
105605
|
-
const { document: document2 } = parseHTML(html);
|
|
105830
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
105606
105831
|
const imgEls = document2.querySelectorAll("img[src]");
|
|
105607
105832
|
let autoIdCounter = 0;
|
|
105608
105833
|
for (const el of imgEls) {
|
|
@@ -105628,14 +105853,14 @@ function parseImageElements(html) {
|
|
|
105628
105853
|
}
|
|
105629
105854
|
return images;
|
|
105630
105855
|
}
|
|
105631
|
-
async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config2) {
|
|
105856
|
+
async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config2, outputDirOverride) {
|
|
105632
105857
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
105633
105858
|
const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
|
|
105634
|
-
const videoOutputDir =
|
|
105635
|
-
if (!
|
|
105859
|
+
const videoOutputDir = outputDirOverride ?? join9(outputDir, videoId);
|
|
105860
|
+
if (!existsSync9(videoOutputDir)) mkdirSync6(videoOutputDir, { recursive: true });
|
|
105636
105861
|
const metadata = await extractMediaMetadata(videoPath);
|
|
105637
|
-
const framePattern =
|
|
105638
|
-
const outputPattern =
|
|
105862
|
+
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format3}`;
|
|
105863
|
+
const outputPattern = join9(videoOutputDir, framePattern);
|
|
105639
105864
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
105640
105865
|
const isMacOS = process.platform === "darwin";
|
|
105641
105866
|
const args = [];
|
|
@@ -105683,9 +105908,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105683
105908
|
return;
|
|
105684
105909
|
}
|
|
105685
105910
|
const framePaths = /* @__PURE__ */ new Map();
|
|
105686
|
-
const files =
|
|
105911
|
+
const files = readdirSync5(videoOutputDir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(`.${format3}`)).sort();
|
|
105687
105912
|
files.forEach((file, index) => {
|
|
105688
|
-
framePaths.set(index,
|
|
105913
|
+
framePaths.set(index, join9(videoOutputDir, file));
|
|
105689
105914
|
});
|
|
105690
105915
|
resolve14({
|
|
105691
105916
|
videoId,
|
|
@@ -105709,12 +105934,19 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
105709
105934
|
});
|
|
105710
105935
|
});
|
|
105711
105936
|
}
|
|
105712
|
-
async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
|
|
105937
|
+
async function convertSdrToHdr(inputPath, outputPath, startTime, duration, targetTransfer, signal, config2) {
|
|
105938
|
+
if (duration <= 0) {
|
|
105939
|
+
throw new Error(`convertSdrToHdr: duration must be positive (got ${duration})`);
|
|
105940
|
+
}
|
|
105713
105941
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
105714
105942
|
const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
|
|
105715
105943
|
const args = [
|
|
105944
|
+
"-ss",
|
|
105945
|
+
String(startTime),
|
|
105716
105946
|
"-i",
|
|
105717
105947
|
inputPath,
|
|
105948
|
+
"-t",
|
|
105949
|
+
String(duration),
|
|
105718
105950
|
"-vf",
|
|
105719
105951
|
"colorspace=all=bt2020:iall=bt709:range=tv",
|
|
105720
105952
|
"-color_primaries",
|
|
@@ -105741,6 +105973,11 @@ async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, co
|
|
|
105741
105973
|
);
|
|
105742
105974
|
}
|
|
105743
105975
|
}
|
|
105976
|
+
function resolveSegmentDuration(requested, mediaStart, metadata) {
|
|
105977
|
+
if (Number.isFinite(requested) && requested > 0) return requested;
|
|
105978
|
+
const sourceRemaining = metadata.durationSeconds - mediaStart;
|
|
105979
|
+
return sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
105980
|
+
}
|
|
105744
105981
|
async function convertVfrToCfr(inputPath, outputPath, targetFps, startTime, duration, signal, config2) {
|
|
105745
105982
|
const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
105746
105983
|
const args = [
|
|
@@ -105777,21 +106014,34 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105777
106014
|
const extracted = [];
|
|
105778
106015
|
const errors = [];
|
|
105779
106016
|
let totalFramesExtracted = 0;
|
|
106017
|
+
const breakdown = {
|
|
106018
|
+
resolveMs: 0,
|
|
106019
|
+
hdrProbeMs: 0,
|
|
106020
|
+
hdrPreflightMs: 0,
|
|
106021
|
+
hdrPreflightCount: 0,
|
|
106022
|
+
vfrProbeMs: 0,
|
|
106023
|
+
vfrPreflightMs: 0,
|
|
106024
|
+
vfrPreflightCount: 0,
|
|
106025
|
+
extractMs: 0,
|
|
106026
|
+
cacheHits: 0,
|
|
106027
|
+
cacheMisses: 0
|
|
106028
|
+
};
|
|
106029
|
+
const phase1Start = Date.now();
|
|
105780
106030
|
const resolvedVideos = [];
|
|
105781
106031
|
for (const video of videos) {
|
|
105782
106032
|
if (signal?.aborted) break;
|
|
105783
106033
|
try {
|
|
105784
106034
|
let videoPath = video.src;
|
|
105785
106035
|
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
105786
|
-
const fromCompiled = compiledDir ?
|
|
105787
|
-
videoPath = fromCompiled &&
|
|
106036
|
+
const fromCompiled = compiledDir ? join9(compiledDir, videoPath) : null;
|
|
106037
|
+
videoPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, videoPath);
|
|
105788
106038
|
}
|
|
105789
106039
|
if (isHttpUrl(videoPath)) {
|
|
105790
|
-
const downloadDir =
|
|
105791
|
-
|
|
106040
|
+
const downloadDir = join9(options.outputDir, "_downloads");
|
|
106041
|
+
mkdirSync6(downloadDir, { recursive: true });
|
|
105792
106042
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
105793
106043
|
}
|
|
105794
|
-
if (!
|
|
106044
|
+
if (!existsSync9(videoPath)) {
|
|
105795
106045
|
errors.push({ videoId: video.id, error: `Video file not found: ${videoPath}` });
|
|
105796
106046
|
continue;
|
|
105797
106047
|
}
|
|
@@ -105800,27 +106050,66 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105800
106050
|
errors.push({ videoId: video.id, error: err instanceof Error ? err.message : String(err) });
|
|
105801
106051
|
}
|
|
105802
106052
|
}
|
|
105803
|
-
|
|
105804
|
-
|
|
105805
|
-
|
|
105806
|
-
|
|
105807
|
-
|
|
106053
|
+
breakdown.resolveMs = Date.now() - phase1Start;
|
|
106054
|
+
const cacheKeyInputs = resolvedVideos.map(({ video, videoPath }) => {
|
|
106055
|
+
const stat = readKeyStat(videoPath);
|
|
106056
|
+
if (!stat) return null;
|
|
106057
|
+
return {
|
|
106058
|
+
videoPath,
|
|
106059
|
+
mtimeMs: stat.mtimeMs,
|
|
106060
|
+
size: stat.size,
|
|
106061
|
+
mediaStart: video.mediaStart,
|
|
106062
|
+
start: video.start,
|
|
106063
|
+
end: video.end
|
|
106064
|
+
};
|
|
106065
|
+
});
|
|
106066
|
+
const phase2ProbeStart = Date.now();
|
|
106067
|
+
const videoMetadata = await Promise.all(
|
|
106068
|
+
resolvedVideos.map(({ videoPath }) => extractMediaMetadata(videoPath))
|
|
105808
106069
|
);
|
|
106070
|
+
const videoColorSpaces = videoMetadata.map((m) => m.colorSpace);
|
|
106071
|
+
breakdown.hdrProbeMs = Date.now() - phase2ProbeStart;
|
|
106072
|
+
const hdrPreflightStart = Date.now();
|
|
105809
106073
|
const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
|
|
106074
|
+
const hdrSkippedIndices = /* @__PURE__ */ new Set();
|
|
105810
106075
|
if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
|
|
105811
106076
|
const targetTransfer = hdrInfo.dominantTransfer;
|
|
105812
|
-
const convertDir =
|
|
105813
|
-
|
|
106077
|
+
const convertDir = join9(options.outputDir, "_hdr_normalized");
|
|
106078
|
+
mkdirSync6(convertDir, { recursive: true });
|
|
105814
106079
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
105815
106080
|
if (signal?.aborted) break;
|
|
105816
106081
|
const cs = videoColorSpaces[i] ?? null;
|
|
105817
106082
|
if (!isHdrColorSpace(cs)) {
|
|
105818
106083
|
const entry = resolvedVideos[i];
|
|
105819
|
-
|
|
105820
|
-
|
|
106084
|
+
const metadata = videoMetadata[i];
|
|
106085
|
+
if (!entry || !metadata) continue;
|
|
106086
|
+
if (entry.video.mediaStart >= metadata.durationSeconds) {
|
|
106087
|
+
errors.push({
|
|
106088
|
+
videoId: entry.video.id,
|
|
106089
|
+
error: `SDR\u2192HDR conversion skipped: mediaStart (${entry.video.mediaStart}s) \u2265 source duration (${metadata.durationSeconds}s)`
|
|
106090
|
+
});
|
|
106091
|
+
hdrSkippedIndices.add(i);
|
|
106092
|
+
continue;
|
|
106093
|
+
}
|
|
106094
|
+
let segDuration = entry.video.end - entry.video.start;
|
|
106095
|
+
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
106096
|
+
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
106097
|
+
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
106098
|
+
}
|
|
106099
|
+
const convertedPath = join9(convertDir, `${entry.video.id}_hdr.mp4`);
|
|
105821
106100
|
try {
|
|
105822
|
-
await convertSdrToHdr(
|
|
106101
|
+
await convertSdrToHdr(
|
|
106102
|
+
entry.videoPath,
|
|
106103
|
+
convertedPath,
|
|
106104
|
+
entry.video.mediaStart,
|
|
106105
|
+
segDuration,
|
|
106106
|
+
targetTransfer,
|
|
106107
|
+
signal,
|
|
106108
|
+
config2
|
|
106109
|
+
);
|
|
105823
106110
|
entry.videoPath = convertedPath;
|
|
106111
|
+
entry.video = { ...entry.video, mediaStart: 0 };
|
|
106112
|
+
breakdown.hdrPreflightCount += 1;
|
|
105824
106113
|
} catch (err) {
|
|
105825
106114
|
errors.push({
|
|
105826
106115
|
videoId: entry.video.id,
|
|
@@ -105830,20 +106119,34 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105830
106119
|
}
|
|
105831
106120
|
}
|
|
105832
106121
|
}
|
|
105833
|
-
|
|
106122
|
+
breakdown.hdrPreflightMs = Date.now() - hdrPreflightStart;
|
|
106123
|
+
if (hdrSkippedIndices.size > 0) {
|
|
106124
|
+
for (let i = resolvedVideos.length - 1; i >= 0; i--) {
|
|
106125
|
+
if (hdrSkippedIndices.has(i)) {
|
|
106126
|
+
resolvedVideos.splice(i, 1);
|
|
106127
|
+
videoMetadata.splice(i, 1);
|
|
106128
|
+
videoColorSpaces.splice(i, 1);
|
|
106129
|
+
cacheKeyInputs.splice(i, 1);
|
|
106130
|
+
}
|
|
106131
|
+
}
|
|
106132
|
+
}
|
|
106133
|
+
const vfrPreflightStart = Date.now();
|
|
106134
|
+
const vfrNormDir = join9(options.outputDir, "_vfr_normalized");
|
|
105834
106135
|
for (let i = 0; i < resolvedVideos.length; i++) {
|
|
105835
106136
|
if (signal?.aborted) break;
|
|
105836
106137
|
const entry = resolvedVideos[i];
|
|
105837
106138
|
if (!entry) continue;
|
|
106139
|
+
const vfrProbeStart = Date.now();
|
|
105838
106140
|
const metadata = await extractMediaMetadata(entry.videoPath);
|
|
106141
|
+
breakdown.vfrProbeMs += Date.now() - vfrProbeStart;
|
|
105839
106142
|
if (!metadata.isVFR) continue;
|
|
105840
106143
|
let segDuration = entry.video.end - entry.video.start;
|
|
105841
106144
|
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
105842
106145
|
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
105843
106146
|
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
105844
106147
|
}
|
|
105845
|
-
|
|
105846
|
-
const normalizedPath =
|
|
106148
|
+
mkdirSync6(vfrNormDir, { recursive: true });
|
|
106149
|
+
const normalizedPath = join9(vfrNormDir, `${entry.video.id}_cfr.mp4`);
|
|
105847
106150
|
try {
|
|
105848
106151
|
await convertVfrToCfr(
|
|
105849
106152
|
entry.videoPath,
|
|
@@ -105856,6 +106159,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105856
106159
|
);
|
|
105857
106160
|
entry.videoPath = normalizedPath;
|
|
105858
106161
|
entry.video = { ...entry.video, mediaStart: 0 };
|
|
106162
|
+
breakdown.vfrPreflightCount += 1;
|
|
105859
106163
|
} catch (err) {
|
|
105860
106164
|
errors.push({
|
|
105861
106165
|
videoId: entry.video.id,
|
|
@@ -105863,19 +106167,72 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105863
106167
|
});
|
|
105864
106168
|
}
|
|
105865
106169
|
}
|
|
106170
|
+
breakdown.vfrPreflightMs = Date.now() - vfrPreflightStart;
|
|
106171
|
+
const phase3Start = Date.now();
|
|
106172
|
+
const cacheRootDir = config2?.extractCacheDir;
|
|
106173
|
+
const cacheFormat = options.format ?? "jpg";
|
|
106174
|
+
async function tryCachedExtract(video, videoPath, videoDuration, i) {
|
|
106175
|
+
if (!cacheRootDir) return null;
|
|
106176
|
+
const keyInput = cacheKeyInputs[i];
|
|
106177
|
+
const probedMeta = videoMetadata[i];
|
|
106178
|
+
if (!keyInput || !probedMeta) return null;
|
|
106179
|
+
const keyDuration = resolveSegmentDuration(
|
|
106180
|
+
keyInput.end - keyInput.start,
|
|
106181
|
+
keyInput.mediaStart,
|
|
106182
|
+
probedMeta
|
|
106183
|
+
);
|
|
106184
|
+
const lookup = lookupCacheEntry(cacheRootDir, {
|
|
106185
|
+
videoPath: keyInput.videoPath,
|
|
106186
|
+
mtimeMs: keyInput.mtimeMs,
|
|
106187
|
+
size: keyInput.size,
|
|
106188
|
+
mediaStart: keyInput.mediaStart,
|
|
106189
|
+
duration: keyDuration,
|
|
106190
|
+
fps: options.fps,
|
|
106191
|
+
format: cacheFormat
|
|
106192
|
+
});
|
|
106193
|
+
if (lookup.hit) {
|
|
106194
|
+
breakdown.cacheHits += 1;
|
|
106195
|
+
const rehydrated = rehydrateCacheEntry(lookup.entry, {
|
|
106196
|
+
videoId: video.id,
|
|
106197
|
+
srcPath: keyInput.videoPath,
|
|
106198
|
+
fps: options.fps,
|
|
106199
|
+
format: cacheFormat,
|
|
106200
|
+
metadata: probedMeta
|
|
106201
|
+
});
|
|
106202
|
+
return { ...rehydrated, ownedByLookup: true };
|
|
106203
|
+
}
|
|
106204
|
+
breakdown.cacheMisses += 1;
|
|
106205
|
+
ensureCacheEntryDir(lookup.entry);
|
|
106206
|
+
const result = await extractVideoFramesRange(
|
|
106207
|
+
videoPath,
|
|
106208
|
+
video.id,
|
|
106209
|
+
video.mediaStart,
|
|
106210
|
+
videoDuration,
|
|
106211
|
+
options,
|
|
106212
|
+
signal,
|
|
106213
|
+
config2,
|
|
106214
|
+
lookup.entry.dir
|
|
106215
|
+
);
|
|
106216
|
+
markCacheEntryComplete(lookup.entry);
|
|
106217
|
+
return { ...result, ownedByLookup: true };
|
|
106218
|
+
}
|
|
105866
106219
|
const results = await Promise.all(
|
|
105867
|
-
resolvedVideos.map(async ({ video, videoPath }) => {
|
|
106220
|
+
resolvedVideos.map(async ({ video, videoPath }, i) => {
|
|
105868
106221
|
if (signal?.aborted) {
|
|
105869
106222
|
throw new Error("Video frame extraction cancelled");
|
|
105870
106223
|
}
|
|
105871
106224
|
try {
|
|
105872
|
-
|
|
105873
|
-
|
|
105874
|
-
|
|
105875
|
-
|
|
105876
|
-
|
|
106225
|
+
const probedMeta = videoMetadata[i] ?? await extractMediaMetadata(videoPath);
|
|
106226
|
+
const videoDuration = resolveSegmentDuration(
|
|
106227
|
+
video.end - video.start,
|
|
106228
|
+
video.mediaStart,
|
|
106229
|
+
probedMeta
|
|
106230
|
+
);
|
|
106231
|
+
if (video.end - video.start !== videoDuration) {
|
|
105877
106232
|
video.end = video.start + videoDuration;
|
|
105878
106233
|
}
|
|
106234
|
+
const cached = await tryCachedExtract(video, videoPath, videoDuration, i);
|
|
106235
|
+
if (cached) return { result: cached };
|
|
105879
106236
|
const result = await extractVideoFramesRange(
|
|
105880
106237
|
videoPath,
|
|
105881
106238
|
video.id,
|
|
@@ -105896,6 +106253,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105896
106253
|
}
|
|
105897
106254
|
})
|
|
105898
106255
|
);
|
|
106256
|
+
breakdown.extractMs = Date.now() - phase3Start;
|
|
105899
106257
|
for (const item of results) {
|
|
105900
106258
|
if ("error" in item && item.error) {
|
|
105901
106259
|
errors.push(item.error);
|
|
@@ -105909,7 +106267,8 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
|
|
|
105909
106267
|
extracted,
|
|
105910
106268
|
errors,
|
|
105911
106269
|
totalFramesExtracted,
|
|
105912
|
-
durationMs: Date.now() - startTime
|
|
106270
|
+
durationMs: Date.now() - startTime,
|
|
106271
|
+
phaseBreakdown: breakdown
|
|
105913
106272
|
};
|
|
105914
106273
|
}
|
|
105915
106274
|
function getFrameAtTime(extracted, globalTime, videoStart) {
|
|
@@ -106002,7 +106361,8 @@ var FrameLookupTable = class {
|
|
|
106002
106361
|
}
|
|
106003
106362
|
cleanup() {
|
|
106004
106363
|
for (const video of this.videos.values()) {
|
|
106005
|
-
if (
|
|
106364
|
+
if (video.extracted.ownedByLookup) continue;
|
|
106365
|
+
if (existsSync9(video.extracted.outputDir)) {
|
|
106006
106366
|
rmSync(video.extracted.outputDir, { recursive: true, force: true });
|
|
106007
106367
|
}
|
|
106008
106368
|
}
|
|
@@ -106025,23 +106385,23 @@ function createFrameLookupTable(videos, extracted) {
|
|
|
106025
106385
|
// ../engine/src/services/videoFrameInjector.ts
|
|
106026
106386
|
import { promises as fs7 } from "fs";
|
|
106027
106387
|
function createFrameDataUriCache(cacheLimit) {
|
|
106028
|
-
const
|
|
106388
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
106029
106389
|
const inFlight = /* @__PURE__ */ new Map();
|
|
106030
106390
|
function remember(framePath, dataUri) {
|
|
106031
|
-
if (
|
|
106032
|
-
|
|
106391
|
+
if (cache2.has(framePath)) {
|
|
106392
|
+
cache2.delete(framePath);
|
|
106033
106393
|
}
|
|
106034
|
-
|
|
106035
|
-
if (
|
|
106036
|
-
const oldestKey =
|
|
106394
|
+
cache2.set(framePath, dataUri);
|
|
106395
|
+
if (cache2.size > cacheLimit) {
|
|
106396
|
+
const oldestKey = cache2.keys().next().value;
|
|
106037
106397
|
if (oldestKey) {
|
|
106038
|
-
|
|
106398
|
+
cache2.delete(oldestKey);
|
|
106039
106399
|
}
|
|
106040
106400
|
}
|
|
106041
106401
|
return dataUri;
|
|
106042
106402
|
}
|
|
106043
106403
|
async function get(framePath) {
|
|
106044
|
-
const cached =
|
|
106404
|
+
const cached = cache2.get(framePath);
|
|
106045
106405
|
if (cached) {
|
|
106046
106406
|
remember(framePath, cached);
|
|
106047
106407
|
return cached;
|
|
@@ -106245,11 +106605,11 @@ async function queryElementStacking(page, nativeHdrIds) {
|
|
|
106245
106605
|
}
|
|
106246
106606
|
|
|
106247
106607
|
// ../engine/src/services/audioMixer.ts
|
|
106248
|
-
import { existsSync as
|
|
106249
|
-
import { isAbsolute as isAbsolute3, join as
|
|
106608
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, rmSync as rmSync2 } from "fs";
|
|
106609
|
+
import { isAbsolute as isAbsolute3, join as join10, dirname as dirname7 } from "path";
|
|
106250
106610
|
function parseAudioElements(html) {
|
|
106251
106611
|
const elements = [];
|
|
106252
|
-
const { document: document2 } = parseHTML(html);
|
|
106612
|
+
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
106253
106613
|
const audioEls = document2.querySelectorAll("audio[id][src]");
|
|
106254
106614
|
for (const el of audioEls) {
|
|
106255
106615
|
const id = el.getAttribute("id");
|
|
@@ -106297,7 +106657,7 @@ function parseAudioElements(html) {
|
|
|
106297
106657
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config2) {
|
|
106298
106658
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
106299
106659
|
const outputDir = dirname7(outputPath);
|
|
106300
|
-
if (!
|
|
106660
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
106301
106661
|
const args = ["-i", videoPath];
|
|
106302
106662
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
106303
106663
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -106324,7 +106684,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
106324
106684
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config2) {
|
|
106325
106685
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
106326
106686
|
const outputDir = dirname7(outputPath);
|
|
106327
|
-
if (!
|
|
106687
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
106328
106688
|
const args = [
|
|
106329
106689
|
"-ss",
|
|
106330
106690
|
String(mediaStart),
|
|
@@ -106360,7 +106720,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
106360
106720
|
async function generateSilence(outputPath, duration, signal, config2) {
|
|
106361
106721
|
const ffmpegProcessTimeout = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
|
|
106362
106722
|
const outputDir = dirname7(outputPath);
|
|
106363
|
-
if (!
|
|
106723
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
106364
106724
|
const args = [
|
|
106365
106725
|
"-f",
|
|
106366
106726
|
"lavfi",
|
|
@@ -106403,7 +106763,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config2
|
|
|
106403
106763
|
};
|
|
106404
106764
|
}
|
|
106405
106765
|
const outputDir = dirname7(outputPath);
|
|
106406
|
-
if (!
|
|
106766
|
+
if (!existsSync10(outputDir)) mkdirSync7(outputDir, { recursive: true });
|
|
106407
106767
|
const inputs = [];
|
|
106408
106768
|
const filterParts = [];
|
|
106409
106769
|
tracks.forEach((track, i) => {
|
|
@@ -106464,7 +106824,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106464
106824
|
const startMs = Date.now();
|
|
106465
106825
|
const tracks = [];
|
|
106466
106826
|
const errors = [];
|
|
106467
|
-
if (!
|
|
106827
|
+
if (!existsSync10(workDir)) mkdirSync7(workDir, { recursive: true });
|
|
106468
106828
|
await Promise.all(
|
|
106469
106829
|
elements.map(async (element) => {
|
|
106470
106830
|
if (signal?.aborted) {
|
|
@@ -106474,8 +106834,8 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106474
106834
|
try {
|
|
106475
106835
|
let srcPath = element.src;
|
|
106476
106836
|
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
106477
|
-
const fromCompiled = compiledDir ?
|
|
106478
|
-
srcPath = fromCompiled &&
|
|
106837
|
+
const fromCompiled = compiledDir ? join10(compiledDir, srcPath) : null;
|
|
106838
|
+
srcPath = fromCompiled && existsSync10(fromCompiled) ? fromCompiled : join10(baseDir, srcPath);
|
|
106479
106839
|
}
|
|
106480
106840
|
if (isHttpUrl(srcPath)) {
|
|
106481
106841
|
try {
|
|
@@ -106487,7 +106847,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106487
106847
|
return;
|
|
106488
106848
|
}
|
|
106489
106849
|
}
|
|
106490
|
-
if (!
|
|
106850
|
+
if (!existsSync10(srcPath)) {
|
|
106491
106851
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
106492
106852
|
return;
|
|
106493
106853
|
}
|
|
@@ -106498,7 +106858,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106498
106858
|
}
|
|
106499
106859
|
let audioSrcPath = srcPath;
|
|
106500
106860
|
if (element.type === "video") {
|
|
106501
|
-
const extractedPath =
|
|
106861
|
+
const extractedPath = join10(workDir, `${element.id}-extracted.wav`);
|
|
106502
106862
|
const extractResult = await extractAudioFromVideo(
|
|
106503
106863
|
srcPath,
|
|
106504
106864
|
extractedPath,
|
|
@@ -106515,7 +106875,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106515
106875
|
}
|
|
106516
106876
|
audioSrcPath = extractedPath;
|
|
106517
106877
|
} else {
|
|
106518
|
-
const trimmedPath =
|
|
106878
|
+
const trimmedPath = join10(workDir, `${element.id}-trimmed.wav`);
|
|
106519
106879
|
const prepResult = await prepareAudioTrack(
|
|
106520
106880
|
srcPath,
|
|
106521
106881
|
trimmedPath,
|
|
@@ -106558,9 +106918,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
106558
106918
|
|
|
106559
106919
|
// ../engine/src/services/parallelCoordinator.ts
|
|
106560
106920
|
import { cpus, freemem, totalmem } from "os";
|
|
106561
|
-
import { existsSync as
|
|
106921
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
106562
106922
|
import { copyFile, rename as rename2 } from "fs/promises";
|
|
106563
|
-
import { join as
|
|
106923
|
+
import { join as join11 } from "path";
|
|
106564
106924
|
var MEMORY_PER_WORKER_MB = 256;
|
|
106565
106925
|
var MIN_WORKERS = 1;
|
|
106566
106926
|
var ABSOLUTE_MAX_WORKERS = 10;
|
|
@@ -106608,7 +106968,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
106608
106968
|
workerId: i,
|
|
106609
106969
|
startFrame,
|
|
106610
106970
|
endFrame,
|
|
106611
|
-
outputDir:
|
|
106971
|
+
outputDir: join11(workDir, `worker-${i}`)
|
|
106612
106972
|
});
|
|
106613
106973
|
}
|
|
106614
106974
|
return tasks;
|
|
@@ -106616,7 +106976,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
106616
106976
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config2) {
|
|
106617
106977
|
const startTime = Date.now();
|
|
106618
106978
|
let framesCaptured = 0;
|
|
106619
|
-
if (!
|
|
106979
|
+
if (!existsSync11(task.outputDir)) mkdirSync8(task.outputDir, { recursive: true });
|
|
106620
106980
|
let session = null;
|
|
106621
106981
|
let perf;
|
|
106622
106982
|
try {
|
|
@@ -106706,17 +107066,17 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
106706
107066
|
return results;
|
|
106707
107067
|
}
|
|
106708
107068
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
106709
|
-
if (!
|
|
107069
|
+
if (!existsSync11(outputDir)) mkdirSync8(outputDir, { recursive: true });
|
|
106710
107070
|
let totalFrames = 0;
|
|
106711
107071
|
const sortedTasks = [...tasks].sort((a, b) => a.startFrame - b.startFrame);
|
|
106712
107072
|
for (const task of sortedTasks) {
|
|
106713
|
-
if (!
|
|
107073
|
+
if (!existsSync11(task.outputDir)) {
|
|
106714
107074
|
continue;
|
|
106715
107075
|
}
|
|
106716
|
-
const files =
|
|
107076
|
+
const files = readdirSync6(task.outputDir).filter((f) => f.startsWith("frame_") && (f.endsWith(".jpg") || f.endsWith(".png"))).sort();
|
|
106717
107077
|
const copyTasks = files.map(async (file) => {
|
|
106718
|
-
const sourcePath =
|
|
106719
|
-
const targetPath =
|
|
107078
|
+
const sourcePath = join11(task.outputDir, file);
|
|
107079
|
+
const targetPath = join11(outputDir, file);
|
|
106720
107080
|
try {
|
|
106721
107081
|
await rename2(sourcePath, targetPath);
|
|
106722
107082
|
} catch {
|
|
@@ -107897,18 +108257,18 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
|
|
|
107897
108257
|
TRANSITIONS["ridged-burn"] = ridgedBurn;
|
|
107898
108258
|
|
|
107899
108259
|
// src/services/renderOrchestrator.ts
|
|
107900
|
-
import { join as
|
|
108260
|
+
import { join as join16, dirname as dirname10, resolve as resolve11 } from "path";
|
|
107901
108261
|
import { randomUUID } from "crypto";
|
|
107902
108262
|
import { freemem as freemem2 } from "os";
|
|
107903
108263
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
107904
108264
|
|
|
107905
108265
|
// src/services/fileServer.ts
|
|
107906
|
-
import { readFileSync as readFileSync7, existsSync as
|
|
107907
|
-
import { join as
|
|
108266
|
+
import { readFileSync as readFileSync7, existsSync as existsSync13, realpathSync, statSync as statSync6 } from "node:fs";
|
|
108267
|
+
import { join as join12, extname as extname4, resolve as resolve8, sep } from "node:path";
|
|
107908
108268
|
|
|
107909
108269
|
// src/services/hyperframeRuntimeLoader.ts
|
|
107910
|
-
import { createHash as
|
|
107911
|
-
import { existsSync as
|
|
108270
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
108271
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6 } from "node:fs";
|
|
107912
108272
|
import { dirname as dirname8, resolve as resolve7 } from "node:path";
|
|
107913
108273
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
107914
108274
|
var PRODUCER_DIR = dirname8(fileURLToPath2(import.meta.url));
|
|
@@ -107935,7 +108295,7 @@ function resolveHyperframeManifestPath() {
|
|
|
107935
108295
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
107936
108296
|
];
|
|
107937
108297
|
for (const candidate of candidates) {
|
|
107938
|
-
if (
|
|
108298
|
+
if (existsSync12(candidate)) {
|
|
107939
108299
|
return candidate;
|
|
107940
108300
|
}
|
|
107941
108301
|
}
|
|
@@ -107946,7 +108306,7 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
107946
108306
|
}
|
|
107947
108307
|
function resolveVerifiedHyperframeRuntime() {
|
|
107948
108308
|
const manifestPath = resolveHyperframeManifestPath();
|
|
107949
|
-
if (!
|
|
108309
|
+
if (!existsSync12(manifestPath)) {
|
|
107950
108310
|
throw new Error(
|
|
107951
108311
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
107952
108312
|
);
|
|
@@ -107960,11 +108320,11 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
107960
108320
|
);
|
|
107961
108321
|
}
|
|
107962
108322
|
const runtimePath = resolve7(dirname8(manifestPath), runtimeFileName);
|
|
107963
|
-
if (!
|
|
108323
|
+
if (!existsSync12(runtimePath)) {
|
|
107964
108324
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
107965
108325
|
}
|
|
107966
108326
|
const runtimeSource = readFileSync6(runtimePath, "utf8");
|
|
107967
|
-
const runtimeSha =
|
|
108327
|
+
const runtimeSha = createHash3("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
107968
108328
|
if (runtimeSha !== manifest.sha256) {
|
|
107969
108329
|
throw new Error(
|
|
107970
108330
|
`[HyperframeRuntimeLoader] Runtime checksum mismatch. expected=${manifest.sha256} actual=${runtimeSha}`
|
|
@@ -107986,8 +108346,8 @@ function isPathInside(child, parent, options = {}) {
|
|
|
107986
108346
|
const separator = pathModule?.sep ?? sep;
|
|
107987
108347
|
const resolvedChild = resolveFn(child);
|
|
107988
108348
|
const resolvedParent = resolveFn(parent);
|
|
107989
|
-
const normalizedChild = resolveSymlinks &&
|
|
107990
|
-
const normalizedParent = resolveSymlinks &&
|
|
108349
|
+
const normalizedChild = resolveSymlinks && existsSync13(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
108350
|
+
const normalizedParent = resolveSymlinks && existsSync13(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
107991
108351
|
if (normalizedChild === normalizedParent) return true;
|
|
107992
108352
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
107993
108353
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -108386,14 +108746,14 @@ function createFileServer2(options) {
|
|
|
108386
108746
|
const relativePath = requestPath.replace(/^\//, "");
|
|
108387
108747
|
let filePath = null;
|
|
108388
108748
|
if (compiledDir) {
|
|
108389
|
-
const candidate =
|
|
108390
|
-
if (
|
|
108749
|
+
const candidate = join12(compiledDir, relativePath);
|
|
108750
|
+
if (existsSync13(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync6(candidate).isFile()) {
|
|
108391
108751
|
filePath = candidate;
|
|
108392
108752
|
}
|
|
108393
108753
|
}
|
|
108394
108754
|
if (!filePath) {
|
|
108395
|
-
const candidate =
|
|
108396
|
-
if (
|
|
108755
|
+
const candidate = join12(projectDir, relativePath);
|
|
108756
|
+
if (existsSync13(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync6(candidate).isFile()) {
|
|
108397
108757
|
filePath = candidate;
|
|
108398
108758
|
}
|
|
108399
108759
|
}
|
|
@@ -108442,12 +108802,12 @@ function createFileServer2(options) {
|
|
|
108442
108802
|
}
|
|
108443
108803
|
|
|
108444
108804
|
// src/services/htmlCompiler.ts
|
|
108445
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
108446
|
-
import { join as
|
|
108805
|
+
import { readFileSync as readFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync10 } from "fs";
|
|
108806
|
+
import { join as join15, dirname as dirname9, resolve as resolve10 } from "path";
|
|
108447
108807
|
import postcss from "postcss";
|
|
108448
108808
|
|
|
108449
108809
|
// src/utils/paths.ts
|
|
108450
|
-
import { resolve as resolve9, basename as basename2, join as
|
|
108810
|
+
import { resolve as resolve9, basename as basename2, join as join13, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
|
|
108451
108811
|
var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
108452
108812
|
function isPathInside2(childPath, parentPath) {
|
|
108453
108813
|
const absChild = resolve9(childPath);
|
|
@@ -108469,15 +108829,15 @@ function toExternalAssetKey(absPath) {
|
|
|
108469
108829
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
108470
108830
|
const absoluteProjectDir = resolve9(projectDir);
|
|
108471
108831
|
const projectName = basename2(absoluteProjectDir);
|
|
108472
|
-
const resolvedOutputPath = outputPath ??
|
|
108832
|
+
const resolvedOutputPath = outputPath ?? join13(rendersDir, `${projectName}.mp4`);
|
|
108473
108833
|
const absoluteOutputPath = resolve9(resolvedOutputPath);
|
|
108474
108834
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
108475
108835
|
}
|
|
108476
108836
|
|
|
108477
108837
|
// src/services/deterministicFonts.ts
|
|
108478
|
-
import { existsSync as
|
|
108838
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "node:fs";
|
|
108479
108839
|
import { homedir as homedir2 } from "node:os";
|
|
108480
|
-
import { join as
|
|
108840
|
+
import { join as join14 } from "node:path";
|
|
108481
108841
|
|
|
108482
108842
|
// src/services/fontData.generated.ts
|
|
108483
108843
|
var EMBEDDED_FONT_DATA = /* @__PURE__ */ new Map([
|
|
@@ -108755,20 +109115,20 @@ function warnUnresolvedFonts(unresolved) {
|
|
|
108755
109115
|
Docs: https://hyperframes.heygen.com/docs/fonts`
|
|
108756
109116
|
);
|
|
108757
109117
|
}
|
|
108758
|
-
var GOOGLE_FONTS_CACHE_DIR =
|
|
109118
|
+
var GOOGLE_FONTS_CACHE_DIR = join14(homedir2(), ".cache", "hyperframes", "fonts");
|
|
108759
109119
|
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";
|
|
108760
109120
|
function fontSlug(familyName) {
|
|
108761
109121
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
108762
109122
|
}
|
|
108763
109123
|
function fontCacheDir(slug) {
|
|
108764
|
-
const dir =
|
|
108765
|
-
if (!
|
|
108766
|
-
|
|
109124
|
+
const dir = join14(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
109125
|
+
if (!existsSync14(dir)) {
|
|
109126
|
+
mkdirSync9(dir, { recursive: true });
|
|
108767
109127
|
}
|
|
108768
109128
|
return dir;
|
|
108769
109129
|
}
|
|
108770
109130
|
function cachedWoff2Path(slug, weight, style) {
|
|
108771
|
-
return
|
|
109131
|
+
return join14(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
108772
109132
|
}
|
|
108773
109133
|
async function fetchGoogleFont(familyName) {
|
|
108774
109134
|
const slug = fontSlug(familyName);
|
|
@@ -108794,12 +109154,12 @@ async function fetchGoogleFont(familyName) {
|
|
|
108794
109154
|
const woff2Url = match2[3] || "";
|
|
108795
109155
|
if (!woff2Url) continue;
|
|
108796
109156
|
const cachePath = cachedWoff2Path(slug, weight, style);
|
|
108797
|
-
if (!
|
|
109157
|
+
if (!existsSync14(cachePath)) {
|
|
108798
109158
|
try {
|
|
108799
109159
|
const fontRes = await fetch(woff2Url);
|
|
108800
109160
|
if (!fontRes.ok) continue;
|
|
108801
109161
|
const buffer = Buffer.from(await fontRes.arrayBuffer());
|
|
108802
|
-
|
|
109162
|
+
writeFileSync4(cachePath, buffer);
|
|
108803
109163
|
} catch {
|
|
108804
109164
|
continue;
|
|
108805
109165
|
}
|
|
@@ -108905,16 +109265,16 @@ function detectRenderModeHints(html) {
|
|
|
108905
109265
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
108906
109266
|
let filePath = src;
|
|
108907
109267
|
if (isHttpUrl(src)) {
|
|
108908
|
-
if (!
|
|
109268
|
+
if (!existsSync15(downloadDir)) mkdirSync10(downloadDir, { recursive: true });
|
|
108909
109269
|
try {
|
|
108910
109270
|
filePath = await downloadToTemp(src, downloadDir);
|
|
108911
109271
|
} catch {
|
|
108912
109272
|
return { duration: 0, resolvedPath: src };
|
|
108913
109273
|
}
|
|
108914
109274
|
} else if (!filePath.startsWith("/")) {
|
|
108915
|
-
filePath =
|
|
109275
|
+
filePath = join15(baseDir, filePath);
|
|
108916
109276
|
}
|
|
108917
|
-
if (!
|
|
109277
|
+
if (!existsSync15(filePath)) {
|
|
108918
109278
|
return { duration: 0, resolvedPath: filePath };
|
|
108919
109279
|
}
|
|
108920
109280
|
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
@@ -108983,7 +109343,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
108983
109343
|
if (visited.has(filePath)) {
|
|
108984
109344
|
continue;
|
|
108985
109345
|
}
|
|
108986
|
-
if (!
|
|
109346
|
+
if (!existsSync15(filePath)) {
|
|
108987
109347
|
continue;
|
|
108988
109348
|
}
|
|
108989
109349
|
const rawSubHtml = readFileSync9(filePath, "utf-8");
|
|
@@ -109193,7 +109553,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
109193
109553
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
109194
109554
|
if (!compHtml) {
|
|
109195
109555
|
const filePath = resolve10(projectDir, srcPath);
|
|
109196
|
-
if (
|
|
109556
|
+
if (existsSync15(filePath)) {
|
|
109197
109557
|
compHtml = readFileSync9(filePath, "utf-8");
|
|
109198
109558
|
}
|
|
109199
109559
|
}
|
|
@@ -109421,7 +109781,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
109421
109781
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
109422
109782
|
return null;
|
|
109423
109783
|
}
|
|
109424
|
-
if (!
|
|
109784
|
+
if (!existsSync15(absPath)) return null;
|
|
109425
109785
|
const safeKey = toExternalAssetKey(absPath);
|
|
109426
109786
|
externalAssets.set(safeKey, absPath);
|
|
109427
109787
|
return safeKey;
|
|
@@ -109617,9 +109977,10 @@ async function recompileWithResolutions(compiled, resolutions, projectDir, downl
|
|
|
109617
109977
|
const mainVideos = parseVideoElements(html);
|
|
109618
109978
|
const mainAudios = parseAudioElements(html);
|
|
109619
109979
|
const mainImages = parseImageElements(html);
|
|
109620
|
-
const
|
|
109621
|
-
const
|
|
109622
|
-
const
|
|
109980
|
+
const hasSubMedia = subVideos.length > 0 || subAudios.length > 0 || subImages.length > 0;
|
|
109981
|
+
const videos = hasSubMedia ? dedupeElementsById([...mainVideos, ...subVideos]) : compiled.videos;
|
|
109982
|
+
const audios = hasSubMedia ? dedupeElementsById([...mainAudios, ...subAudios]) : compiled.audios;
|
|
109983
|
+
const images = hasSubMedia ? dedupeElementsById([...mainImages, ...subImages]) : compiled.images;
|
|
109623
109984
|
const remaining = compiled.unresolvedCompositions.filter(
|
|
109624
109985
|
(c) => !resolutions.some((r) => r.id === c.id)
|
|
109625
109986
|
);
|
|
@@ -109674,24 +110035,21 @@ function createConsoleLogger(level = "info") {
|
|
|
109674
110035
|
}
|
|
109675
110036
|
var defaultLogger = createConsoleLogger("info");
|
|
109676
110037
|
|
|
109677
|
-
// src/services/
|
|
109678
|
-
|
|
109679
|
-
|
|
109680
|
-
await fn();
|
|
109681
|
-
} catch (err) {
|
|
109682
|
-
log.debug(`Cleanup failed (${label})`, {
|
|
109683
|
-
error: err instanceof Error ? err.message : String(err)
|
|
109684
|
-
});
|
|
109685
|
-
}
|
|
109686
|
-
}
|
|
109687
|
-
var frameDirMaxIndexCache = /* @__PURE__ */ new Map();
|
|
110038
|
+
// src/services/frameDirCache.ts
|
|
110039
|
+
import { readdirSync as readdirSync7 } from "fs";
|
|
110040
|
+
var cache = /* @__PURE__ */ new Map();
|
|
109688
110041
|
var FRAME_FILENAME_RE = /^frame_(\d+)\.png$/;
|
|
110042
|
+
var MAX_ENTRIES = 1e3;
|
|
109689
110043
|
function getMaxFrameIndex(frameDir) {
|
|
109690
|
-
const cached =
|
|
109691
|
-
if (cached !== void 0)
|
|
110044
|
+
const cached = cache.get(frameDir);
|
|
110045
|
+
if (cached !== void 0) {
|
|
110046
|
+
cache.delete(frameDir);
|
|
110047
|
+
cache.set(frameDir, cached);
|
|
110048
|
+
return cached;
|
|
110049
|
+
}
|
|
109692
110050
|
let max = 0;
|
|
109693
110051
|
try {
|
|
109694
|
-
for (const name of
|
|
110052
|
+
for (const name of readdirSync7(frameDir)) {
|
|
109695
110053
|
const m = FRAME_FILENAME_RE.exec(name);
|
|
109696
110054
|
if (!m) continue;
|
|
109697
110055
|
const n = Number(m[1]);
|
|
@@ -109699,9 +110057,113 @@ function getMaxFrameIndex(frameDir) {
|
|
|
109699
110057
|
}
|
|
109700
110058
|
} catch {
|
|
109701
110059
|
}
|
|
109702
|
-
|
|
110060
|
+
if (cache.size >= MAX_ENTRIES) {
|
|
110061
|
+
const oldest = cache.keys().next().value;
|
|
110062
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
110063
|
+
}
|
|
110064
|
+
cache.set(frameDir, max);
|
|
109703
110065
|
return max;
|
|
109704
110066
|
}
|
|
110067
|
+
function clearMaxFrameIndex(frameDir) {
|
|
110068
|
+
return cache.delete(frameDir);
|
|
110069
|
+
}
|
|
110070
|
+
|
|
110071
|
+
// src/services/hdrImageTransferCache.ts
|
|
110072
|
+
var DEFAULT_MAX_BYTES = 200 * 1024 * 1024;
|
|
110073
|
+
function createHdrImageTransferCache(options = {}) {
|
|
110074
|
+
const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
110075
|
+
if (!Number.isInteger(maxBytes) || maxBytes < 0) {
|
|
110076
|
+
throw new Error(
|
|
110077
|
+
`createHdrImageTransferCache: maxBytes must be a non-negative integer, got ${String(maxBytes)}`
|
|
110078
|
+
);
|
|
110079
|
+
}
|
|
110080
|
+
const entries2 = /* @__PURE__ */ new Map();
|
|
110081
|
+
let totalBytes = 0;
|
|
110082
|
+
function makeKey(imageId, targetTransfer) {
|
|
110083
|
+
return `${imageId}|${targetTransfer}`;
|
|
110084
|
+
}
|
|
110085
|
+
function evictUntilRoom(needed) {
|
|
110086
|
+
while (totalBytes + needed > maxBytes && entries2.size > 0) {
|
|
110087
|
+
const lruKey = entries2.keys().next().value;
|
|
110088
|
+
if (lruKey === void 0) break;
|
|
110089
|
+
const evicted = entries2.get(lruKey);
|
|
110090
|
+
if (evicted) totalBytes -= evicted.byteLength;
|
|
110091
|
+
entries2.delete(lruKey);
|
|
110092
|
+
}
|
|
110093
|
+
}
|
|
110094
|
+
return {
|
|
110095
|
+
getConverted(imageId, sourceTransfer, targetTransfer, source2) {
|
|
110096
|
+
if (sourceTransfer === targetTransfer) {
|
|
110097
|
+
return source2;
|
|
110098
|
+
}
|
|
110099
|
+
if (maxBytes === 0) {
|
|
110100
|
+
const fresh = Buffer.from(source2);
|
|
110101
|
+
convertTransfer(fresh, sourceTransfer, targetTransfer);
|
|
110102
|
+
return fresh;
|
|
110103
|
+
}
|
|
110104
|
+
const key2 = makeKey(imageId, targetTransfer);
|
|
110105
|
+
const existing = entries2.get(key2);
|
|
110106
|
+
if (existing) {
|
|
110107
|
+
entries2.delete(key2);
|
|
110108
|
+
entries2.set(key2, existing);
|
|
110109
|
+
return existing;
|
|
110110
|
+
}
|
|
110111
|
+
const converted = Buffer.from(source2);
|
|
110112
|
+
convertTransfer(converted, sourceTransfer, targetTransfer);
|
|
110113
|
+
if (converted.byteLength > maxBytes) {
|
|
110114
|
+
return converted;
|
|
110115
|
+
}
|
|
110116
|
+
evictUntilRoom(converted.byteLength);
|
|
110117
|
+
entries2.set(key2, converted);
|
|
110118
|
+
totalBytes += converted.byteLength;
|
|
110119
|
+
return converted;
|
|
110120
|
+
},
|
|
110121
|
+
size() {
|
|
110122
|
+
return entries2.size;
|
|
110123
|
+
},
|
|
110124
|
+
bytesUsed() {
|
|
110125
|
+
return totalBytes;
|
|
110126
|
+
}
|
|
110127
|
+
};
|
|
110128
|
+
}
|
|
110129
|
+
|
|
110130
|
+
// src/services/renderOrchestrator.ts
|
|
110131
|
+
async function safeCleanup(label, fn, log = defaultLogger) {
|
|
110132
|
+
try {
|
|
110133
|
+
await fn();
|
|
110134
|
+
} catch (err) {
|
|
110135
|
+
log.debug(`Cleanup failed (${label})`, {
|
|
110136
|
+
error: err instanceof Error ? err.message : String(err)
|
|
110137
|
+
});
|
|
110138
|
+
}
|
|
110139
|
+
}
|
|
110140
|
+
function sampleDirectoryBytes(dir) {
|
|
110141
|
+
let total = 0;
|
|
110142
|
+
const stack = [dir];
|
|
110143
|
+
while (stack.length > 0) {
|
|
110144
|
+
const current = stack.pop();
|
|
110145
|
+
if (!current) continue;
|
|
110146
|
+
let entries2 = [];
|
|
110147
|
+
try {
|
|
110148
|
+
entries2 = readdirSync8(current);
|
|
110149
|
+
} catch {
|
|
110150
|
+
continue;
|
|
110151
|
+
}
|
|
110152
|
+
for (const name of entries2) {
|
|
110153
|
+
const full = join16(current, name);
|
|
110154
|
+
try {
|
|
110155
|
+
const st = statSync7(full);
|
|
110156
|
+
if (st.isDirectory()) {
|
|
110157
|
+
stack.push(full);
|
|
110158
|
+
} else if (st.isFile()) {
|
|
110159
|
+
total += st.size;
|
|
110160
|
+
}
|
|
110161
|
+
} catch {
|
|
110162
|
+
}
|
|
110163
|
+
}
|
|
110164
|
+
}
|
|
110165
|
+
return total;
|
|
110166
|
+
}
|
|
109705
110167
|
function countNonZeroAlpha(rgba) {
|
|
109706
110168
|
let n = 0;
|
|
109707
110169
|
for (let p = 3; p < rgba.length; p += 4) {
|
|
@@ -109725,6 +110187,10 @@ var RenderCancelledError = class extends Error {
|
|
|
109725
110187
|
this.reason = reason;
|
|
109726
110188
|
}
|
|
109727
110189
|
};
|
|
110190
|
+
var BROWSER_MEDIA_EPSILON = 1e-4;
|
|
110191
|
+
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
110192
|
+
return browserEnd + (existingStart - browserStart);
|
|
110193
|
+
}
|
|
109728
110194
|
function updateJobStatus(job, status, stage, progress, onProgress) {
|
|
109729
110195
|
job.status = status;
|
|
109730
110196
|
job.currentStage = stage;
|
|
@@ -109768,21 +110234,21 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
109768
110234
|
};
|
|
109769
110235
|
}
|
|
109770
110236
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
109771
|
-
const compileDir =
|
|
109772
|
-
|
|
109773
|
-
|
|
110237
|
+
const compileDir = join16(workDir, "compiled");
|
|
110238
|
+
mkdirSync11(compileDir, { recursive: true });
|
|
110239
|
+
writeFileSync5(join16(compileDir, "index.html"), compiled.html, "utf-8");
|
|
109774
110240
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
109775
|
-
const outPath =
|
|
109776
|
-
|
|
109777
|
-
|
|
110241
|
+
const outPath = join16(compileDir, srcPath);
|
|
110242
|
+
mkdirSync11(dirname10(outPath), { recursive: true });
|
|
110243
|
+
writeFileSync5(outPath, html, "utf-8");
|
|
109778
110244
|
}
|
|
109779
110245
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
109780
|
-
const outPath = resolve11(
|
|
110246
|
+
const outPath = resolve11(join16(compileDir, relativePath));
|
|
109781
110247
|
if (!isPathInside2(outPath, compileDir)) {
|
|
109782
110248
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
109783
110249
|
continue;
|
|
109784
110250
|
}
|
|
109785
|
-
|
|
110251
|
+
mkdirSync11(dirname10(outPath), { recursive: true });
|
|
109786
110252
|
copyFileSync2(absolutePath, outPath);
|
|
109787
110253
|
}
|
|
109788
110254
|
if (includeSummary) {
|
|
@@ -109807,7 +110273,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
109807
110273
|
subCompositions: Array.from(compiled.subCompositions.keys()),
|
|
109808
110274
|
renderModeHints: compiled.renderModeHints
|
|
109809
110275
|
};
|
|
109810
|
-
|
|
110276
|
+
writeFileSync5(join16(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
109811
110277
|
}
|
|
109812
110278
|
}
|
|
109813
110279
|
function applyRenderModeHints(cfg, compiled, log = defaultLogger) {
|
|
@@ -109828,8 +110294,8 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
109828
110294
|
if (videoFrameIndex < 1) return;
|
|
109829
110295
|
const maxIndex = getMaxFrameIndex(frameDir);
|
|
109830
110296
|
const effectiveIndex = maxIndex > 0 ? Math.min(videoFrameIndex, maxIndex) : videoFrameIndex;
|
|
109831
|
-
const framePath =
|
|
109832
|
-
if (!
|
|
110297
|
+
const framePath = join16(frameDir, `frame_${String(effectiveIndex).padStart(4, "0")}.png`);
|
|
110298
|
+
if (!existsSync16(framePath)) {
|
|
109833
110299
|
return;
|
|
109834
110300
|
}
|
|
109835
110301
|
try {
|
|
@@ -109875,17 +110341,13 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
109875
110341
|
}
|
|
109876
110342
|
}
|
|
109877
110343
|
}
|
|
109878
|
-
function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sourceTransfer, targetTransfer) {
|
|
110344
|
+
function blitHdrImageLayer(canvas, el, hdrImageBuffers, hdrImageTransferCache, width, height, log, sourceTransfer, targetTransfer) {
|
|
109879
110345
|
const buf = hdrImageBuffers.get(el.id);
|
|
109880
110346
|
if (!buf) {
|
|
109881
110347
|
return;
|
|
109882
110348
|
}
|
|
109883
110349
|
try {
|
|
109884
|
-
|
|
109885
|
-
if (sourceTransfer && targetTransfer && sourceTransfer !== targetTransfer) {
|
|
109886
|
-
hdrRgb = Buffer.from(buf.data);
|
|
109887
|
-
convertTransfer(hdrRgb, sourceTransfer, targetTransfer);
|
|
109888
|
-
}
|
|
110350
|
+
const hdrRgb = sourceTransfer && targetTransfer ? hdrImageTransferCache.getConverted(el.id, sourceTransfer, targetTransfer, buf.data) : buf.data;
|
|
109889
110351
|
const viewportMatrix = parseTransformMatrix(el.transform);
|
|
109890
110352
|
const br = el.borderRadius;
|
|
109891
110353
|
const hasBorderRadius = br[0] > 0 || br[1] > 0 || br[2] > 0 || br[3] > 0;
|
|
@@ -109935,6 +110397,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109935
110397
|
effectiveHdr,
|
|
109936
110398
|
nativeHdrImageIds,
|
|
109937
110399
|
hdrImageBuffers,
|
|
110400
|
+
hdrImageTransferCache,
|
|
109938
110401
|
hdrFrameDirs,
|
|
109939
110402
|
hdrVideoStartTimes,
|
|
109940
110403
|
imageTransfers,
|
|
@@ -109974,6 +110437,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
109974
110437
|
canvas,
|
|
109975
110438
|
layer.element,
|
|
109976
110439
|
hdrImageBuffers,
|
|
110440
|
+
hdrImageTransferCache,
|
|
109977
110441
|
width,
|
|
109978
110442
|
height,
|
|
109979
110443
|
log,
|
|
@@ -110014,7 +110478,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
110014
110478
|
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
110015
110479
|
const localTime = time - startTime;
|
|
110016
110480
|
const frameNum = Math.floor(localTime * fps) + 1;
|
|
110017
|
-
const expectedFrame = frameDir ?
|
|
110481
|
+
const expectedFrame = frameDir ? join16(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
110018
110482
|
log.info("[diag] hdr layer blit", {
|
|
110019
110483
|
frame: debugFrameIndex,
|
|
110020
110484
|
layerIdx,
|
|
@@ -110026,7 +110490,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
110026
110490
|
localTime: localTime.toFixed(3),
|
|
110027
110491
|
hdrFrameNum: frameNum,
|
|
110028
110492
|
expectedFrame,
|
|
110029
|
-
expectedFrameExists: expectedFrame ?
|
|
110493
|
+
expectedFrameExists: expectedFrame ? existsSync16(expectedFrame) : false
|
|
110030
110494
|
});
|
|
110031
110495
|
}
|
|
110032
110496
|
}
|
|
@@ -110051,8 +110515,8 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
110051
110515
|
if (shouldLog && debugDumpDir) {
|
|
110052
110516
|
const after2 = countNonZeroRgb48(canvas);
|
|
110053
110517
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
110054
|
-
const dumpPath =
|
|
110055
|
-
|
|
110518
|
+
const dumpPath = join16(debugDumpDir, dumpName);
|
|
110519
|
+
writeFileSync5(dumpPath, domPng);
|
|
110056
110520
|
log.info("[diag] dom layer blit", {
|
|
110057
110521
|
frame: debugFrameIndex,
|
|
110058
110522
|
layerIdx,
|
|
@@ -110125,8 +110589,8 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
110125
110589
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
110126
110590
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
110127
110591
|
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
|
|
110128
|
-
const debugDir =
|
|
110129
|
-
const workDir = job.config.debug ?
|
|
110592
|
+
const debugDir = join16(producerRoot, ".debug");
|
|
110593
|
+
const workDir = job.config.debug ? join16(debugDir, job.id) : join16(dirname10(outputPath), `work-${job.id}`);
|
|
110130
110594
|
const pipelineStart = Date.now();
|
|
110131
110595
|
const log = job.config.logger ?? defaultLogger;
|
|
110132
110596
|
let fileServer = null;
|
|
@@ -110138,7 +110602,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110138
110602
|
videoExtractionFailures: 0,
|
|
110139
110603
|
imageDecodeFailures: 0
|
|
110140
110604
|
};
|
|
110141
|
-
const perfOutputPath =
|
|
110605
|
+
const perfOutputPath = join16(workDir, "perf-summary.json");
|
|
110142
110606
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
110143
110607
|
const outputFormat = job.config.format ?? "mp4";
|
|
110144
110608
|
const isWebm = outputFormat === "webm";
|
|
@@ -110171,22 +110635,22 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110171
110635
|
};
|
|
110172
110636
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
110173
110637
|
assertNotAborted();
|
|
110174
|
-
if (!
|
|
110638
|
+
if (!existsSync16(workDir)) mkdirSync11(workDir, { recursive: true });
|
|
110175
110639
|
if (job.config.debug) {
|
|
110176
|
-
const logPath =
|
|
110640
|
+
const logPath = join16(workDir, "render.log");
|
|
110177
110641
|
restoreLogger = installDebugLogger(logPath, log);
|
|
110178
110642
|
}
|
|
110179
110643
|
const entryFile = job.config.entryFile || "index.html";
|
|
110180
|
-
let htmlPath =
|
|
110181
|
-
if (!
|
|
110644
|
+
let htmlPath = join16(projectDir, entryFile);
|
|
110645
|
+
if (!existsSync16(htmlPath)) {
|
|
110182
110646
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
110183
110647
|
}
|
|
110184
110648
|
assertNotAborted();
|
|
110185
110649
|
const rawEntry = readFileSync10(htmlPath, "utf-8");
|
|
110186
110650
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
110187
|
-
const wrapperPath =
|
|
110188
|
-
const projectIndexPath =
|
|
110189
|
-
if (!
|
|
110651
|
+
const wrapperPath = join16(workDir, "standalone-entry.html");
|
|
110652
|
+
const projectIndexPath = join16(projectDir, "index.html");
|
|
110653
|
+
if (!existsSync16(projectIndexPath)) {
|
|
110190
110654
|
throw new Error(
|
|
110191
110655
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
110192
110656
|
);
|
|
@@ -110200,7 +110664,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110200
110664
|
`Entry file "${entryFile}" is not mounted from index.html via data-composition-src, so it cannot be rendered independently.`
|
|
110201
110665
|
);
|
|
110202
110666
|
}
|
|
110203
|
-
|
|
110667
|
+
writeFileSync5(wrapperPath, standaloneHtml, "utf-8");
|
|
110204
110668
|
htmlPath = wrapperPath;
|
|
110205
110669
|
log.info("Extracted standalone entry from index.html host context", {
|
|
110206
110670
|
entryFile
|
|
@@ -110209,7 +110673,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110209
110673
|
const stage1Start = Date.now();
|
|
110210
110674
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
110211
110675
|
const compileStart = Date.now();
|
|
110212
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
110676
|
+
let compiled = await compileForRender(projectDir, htmlPath, join16(workDir, "downloads"));
|
|
110213
110677
|
assertNotAborted();
|
|
110214
110678
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
110215
110679
|
applyRenderModeHints(cfg, compiled, log);
|
|
@@ -110241,7 +110705,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110241
110705
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
110242
110706
|
fileServer = await createFileServer2({
|
|
110243
110707
|
projectDir,
|
|
110244
|
-
compiledDir:
|
|
110708
|
+
compiledDir: join16(workDir, "compiled"),
|
|
110245
110709
|
port: 0,
|
|
110246
110710
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
110247
110711
|
});
|
|
@@ -110255,7 +110719,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110255
110719
|
};
|
|
110256
110720
|
probeSession = await createCaptureSession(
|
|
110257
110721
|
fileServer.url,
|
|
110258
|
-
|
|
110722
|
+
join16(workDir, "probe"),
|
|
110259
110723
|
captureOpts,
|
|
110260
110724
|
null,
|
|
110261
110725
|
cfg
|
|
@@ -110287,7 +110751,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110287
110751
|
compiled,
|
|
110288
110752
|
resolutions,
|
|
110289
110753
|
projectDir,
|
|
110290
|
-
|
|
110754
|
+
join16(workDir, "downloads")
|
|
110291
110755
|
);
|
|
110292
110756
|
assertNotAborted();
|
|
110293
110757
|
composition.videos = compiled.videos;
|
|
@@ -110314,10 +110778,15 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110314
110778
|
if (existing.src !== src) {
|
|
110315
110779
|
existing.src = src;
|
|
110316
110780
|
}
|
|
110317
|
-
|
|
110318
|
-
existing.
|
|
110781
|
+
const projectedEnd = projectBrowserEndToCompositionTimeline(
|
|
110782
|
+
existing.start,
|
|
110783
|
+
el.start,
|
|
110784
|
+
el.end
|
|
110785
|
+
);
|
|
110786
|
+
if (projectedEnd > 0 && (existing.end <= 0 || Math.abs(existing.end - projectedEnd) > BROWSER_MEDIA_EPSILON)) {
|
|
110787
|
+
existing.end = projectedEnd;
|
|
110319
110788
|
}
|
|
110320
|
-
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) >
|
|
110789
|
+
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) > BROWSER_MEDIA_EPSILON)) {
|
|
110321
110790
|
existing.mediaStart = el.mediaStart;
|
|
110322
110791
|
}
|
|
110323
110792
|
if (el.hasAudio && !existing.hasAudio) {
|
|
@@ -110342,13 +110811,18 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110342
110811
|
if (existing.src !== src) {
|
|
110343
110812
|
existing.src = src;
|
|
110344
110813
|
}
|
|
110345
|
-
|
|
110346
|
-
existing.
|
|
110814
|
+
const projectedEnd = projectBrowserEndToCompositionTimeline(
|
|
110815
|
+
existing.start,
|
|
110816
|
+
el.start,
|
|
110817
|
+
el.end
|
|
110818
|
+
);
|
|
110819
|
+
if (projectedEnd > 0 && (existing.end <= 0 || Math.abs(existing.end - projectedEnd) > BROWSER_MEDIA_EPSILON)) {
|
|
110820
|
+
existing.end = projectedEnd;
|
|
110347
110821
|
}
|
|
110348
|
-
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) >
|
|
110822
|
+
if (el.mediaStart > 0 && (existing.mediaStart <= 0 || Math.abs(existing.mediaStart - el.mediaStart) > BROWSER_MEDIA_EPSILON)) {
|
|
110349
110823
|
existing.mediaStart = el.mediaStart;
|
|
110350
110824
|
}
|
|
110351
|
-
if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) >
|
|
110825
|
+
if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) > BROWSER_MEDIA_EPSILON) {
|
|
110352
110826
|
existing.volume = el.volume;
|
|
110353
110827
|
}
|
|
110354
110828
|
}
|
|
@@ -110427,7 +110901,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110427
110901
|
const stage2Start = Date.now();
|
|
110428
110902
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
110429
110903
|
let frameLookup = null;
|
|
110430
|
-
const compiledDir =
|
|
110904
|
+
const compiledDir = join16(workDir, "compiled");
|
|
110431
110905
|
let extractionResult = null;
|
|
110432
110906
|
const nativeHdrVideoIds = /* @__PURE__ */ new Set();
|
|
110433
110907
|
const videoTransfers = /* @__PURE__ */ new Map();
|
|
@@ -110436,10 +110910,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110436
110910
|
composition.videos.map(async (v) => {
|
|
110437
110911
|
let videoPath = v.src;
|
|
110438
110912
|
if (!videoPath.startsWith("/")) {
|
|
110439
|
-
const fromCompiled =
|
|
110913
|
+
const fromCompiled = existsSync16(join16(compiledDir, videoPath)) ? join16(compiledDir, videoPath) : join16(projectDir, videoPath);
|
|
110440
110914
|
videoPath = fromCompiled;
|
|
110441
110915
|
}
|
|
110442
|
-
if (!
|
|
110916
|
+
if (!existsSync16(videoPath)) return;
|
|
110443
110917
|
const meta = await extractMediaMetadata(videoPath);
|
|
110444
110918
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110445
110919
|
nativeHdrVideoIds.add(v.id);
|
|
@@ -110457,10 +110931,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110457
110931
|
composition.images.map(async (img) => {
|
|
110458
110932
|
let imgPath = img.src;
|
|
110459
110933
|
if (!imgPath.startsWith("/")) {
|
|
110460
|
-
const fromCompiled =
|
|
110934
|
+
const fromCompiled = existsSync16(join16(compiledDir, imgPath)) ? join16(compiledDir, imgPath) : join16(projectDir, imgPath);
|
|
110461
110935
|
imgPath = fromCompiled;
|
|
110462
110936
|
}
|
|
110463
|
-
if (!
|
|
110937
|
+
if (!existsSync16(imgPath)) return null;
|
|
110464
110938
|
const meta = await extractMediaMetadata(imgPath);
|
|
110465
110939
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
110466
110940
|
nativeHdrImageIds.add(img.id);
|
|
@@ -110476,9 +110950,9 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110476
110950
|
extractionResult = await extractAllVideoFrames(
|
|
110477
110951
|
composition.videos,
|
|
110478
110952
|
projectDir,
|
|
110479
|
-
{ fps: job.config.fps, outputDir:
|
|
110953
|
+
{ fps: job.config.fps, outputDir: join16(workDir, "video-frames") },
|
|
110480
110954
|
abortSignal,
|
|
110481
|
-
|
|
110955
|
+
{ extractCacheDir: cfg.extractCacheDir },
|
|
110482
110956
|
compiledDir
|
|
110483
110957
|
);
|
|
110484
110958
|
assertNotAborted();
|
|
@@ -110534,13 +111008,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110534
111008
|
}
|
|
110535
111009
|
const stage3Start = Date.now();
|
|
110536
111010
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
110537
|
-
const audioOutputPath =
|
|
111011
|
+
const audioOutputPath = join16(workDir, "audio.aac");
|
|
110538
111012
|
let hasAudio = false;
|
|
110539
111013
|
if (composition.audios.length > 0) {
|
|
110540
111014
|
const audioResult = await processCompositionAudio(
|
|
110541
111015
|
composition.audios,
|
|
110542
111016
|
projectDir,
|
|
110543
|
-
|
|
111017
|
+
join16(workDir, "audio-work"),
|
|
110544
111018
|
audioOutputPath,
|
|
110545
111019
|
job.duration,
|
|
110546
111020
|
abortSignal,
|
|
@@ -110558,14 +111032,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110558
111032
|
if (!fileServer) {
|
|
110559
111033
|
fileServer = await createFileServer2({
|
|
110560
111034
|
projectDir,
|
|
110561
|
-
compiledDir:
|
|
111035
|
+
compiledDir: join16(workDir, "compiled"),
|
|
110562
111036
|
port: 0,
|
|
110563
111037
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
110564
111038
|
});
|
|
110565
111039
|
assertNotAborted();
|
|
110566
111040
|
}
|
|
110567
|
-
const framesDir =
|
|
110568
|
-
if (!
|
|
111041
|
+
const framesDir = join16(workDir, "captured-frames");
|
|
111042
|
+
if (!existsSync16(framesDir)) mkdirSync11(framesDir, { recursive: true });
|
|
110569
111043
|
const captureOptions = {
|
|
110570
111044
|
width,
|
|
110571
111045
|
height,
|
|
@@ -110580,7 +111054,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110580
111054
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
110581
111055
|
const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
110582
111056
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
110583
|
-
const videoOnlyPath =
|
|
111057
|
+
const videoOnlyPath = join16(workDir, `video-only${videoExt}`);
|
|
110584
111058
|
const nativeHdrIds = /* @__PURE__ */ new Set([...nativeHdrVideoIds, ...nativeHdrImageIds]);
|
|
110585
111059
|
const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
|
|
110586
111060
|
const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
|
|
@@ -110602,8 +111076,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110602
111076
|
if (!hdrVideoIds.includes(v.id)) continue;
|
|
110603
111077
|
let srcPath = v.src;
|
|
110604
111078
|
if (!srcPath.startsWith("/")) {
|
|
110605
|
-
const fromCompiled =
|
|
110606
|
-
srcPath =
|
|
111079
|
+
const fromCompiled = join16(compiledDir, srcPath);
|
|
111080
|
+
srcPath = existsSync16(fromCompiled) ? fromCompiled : join16(projectDir, srcPath);
|
|
110607
111081
|
}
|
|
110608
111082
|
hdrVideoSrcPaths.set(v.id, srcPath);
|
|
110609
111083
|
}
|
|
@@ -110733,8 +111207,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110733
111207
|
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
110734
111208
|
const video = composition.videos.find((v) => v.id === videoId);
|
|
110735
111209
|
if (!video) continue;
|
|
110736
|
-
const frameDir =
|
|
110737
|
-
|
|
111210
|
+
const frameDir = join16(framesDir, `hdr_${videoId}`);
|
|
111211
|
+
mkdirSync11(frameDir, { recursive: true });
|
|
110738
111212
|
const duration = video.end - video.start;
|
|
110739
111213
|
const dims = hdrExtractionDims.get(videoId) ?? { width, height };
|
|
110740
111214
|
const ffmpegArgs = [
|
|
@@ -110753,7 +111227,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110753
111227
|
"-c:v",
|
|
110754
111228
|
"png",
|
|
110755
111229
|
"-y",
|
|
110756
|
-
|
|
111230
|
+
join16(frameDir, "frame_%04d.png")
|
|
110757
111231
|
];
|
|
110758
111232
|
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
110759
111233
|
if (!result.success) {
|
|
@@ -110821,15 +111295,19 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110821
111295
|
}
|
|
110822
111296
|
}
|
|
110823
111297
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
110824
|
-
const debugDumpDir = debugDumpEnabled ?
|
|
110825
|
-
if (debugDumpDir && !
|
|
110826
|
-
|
|
111298
|
+
const debugDumpDir = debugDumpEnabled ? join16(framesDir, "debug-composite") : null;
|
|
111299
|
+
if (debugDumpDir && !existsSync16(debugDumpDir)) {
|
|
111300
|
+
mkdirSync11(debugDumpDir, { recursive: true });
|
|
110827
111301
|
}
|
|
110828
111302
|
if (!effectiveHdr) {
|
|
110829
111303
|
throw new Error(
|
|
110830
111304
|
"Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
|
|
110831
111305
|
);
|
|
110832
111306
|
}
|
|
111307
|
+
const hdrCacheMaxBytes = process.env.HDR_TRANSFER_CACHE_MAX_BYTES ? Number(process.env.HDR_TRANSFER_CACHE_MAX_BYTES) : void 0;
|
|
111308
|
+
const hdrImageTransferCache = createHdrImageTransferCache(
|
|
111309
|
+
hdrCacheMaxBytes !== void 0 ? { maxBytes: hdrCacheMaxBytes } : {}
|
|
111310
|
+
);
|
|
110833
111311
|
const hdrCompositeCtx = {
|
|
110834
111312
|
log,
|
|
110835
111313
|
domSession,
|
|
@@ -110840,6 +111318,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110840
111318
|
effectiveHdr,
|
|
110841
111319
|
nativeHdrImageIds,
|
|
110842
111320
|
hdrImageBuffers,
|
|
111321
|
+
hdrImageTransferCache,
|
|
110843
111322
|
hdrFrameDirs,
|
|
110844
111323
|
hdrVideoStartTimes,
|
|
110845
111324
|
imageTransfers,
|
|
@@ -110900,6 +111379,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110900
111379
|
sceneBuf,
|
|
110901
111380
|
el,
|
|
110902
111381
|
hdrImageBuffers,
|
|
111382
|
+
hdrImageTransferCache,
|
|
110903
111383
|
width,
|
|
110904
111384
|
height,
|
|
110905
111385
|
log,
|
|
@@ -110963,11 +111443,11 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110963
111443
|
i
|
|
110964
111444
|
);
|
|
110965
111445
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
110966
|
-
const previewPath =
|
|
111446
|
+
const previewPath = join16(
|
|
110967
111447
|
debugDumpDir,
|
|
110968
111448
|
`frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
|
|
110969
111449
|
);
|
|
110970
|
-
|
|
111450
|
+
writeFileSync5(previewPath, normalCanvas);
|
|
110971
111451
|
}
|
|
110972
111452
|
hdrEncoder.writeFrame(normalCanvas);
|
|
110973
111453
|
}
|
|
@@ -110987,7 +111467,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
110987
111467
|
error: err instanceof Error ? err.message : String(err)
|
|
110988
111468
|
});
|
|
110989
111469
|
}
|
|
110990
|
-
|
|
111470
|
+
clearMaxFrameIndex(frameDir);
|
|
110991
111471
|
hdrFrameDirs.delete(videoId);
|
|
110992
111472
|
}
|
|
110993
111473
|
cleanedUpVideos.add(videoId);
|
|
@@ -111038,7 +111518,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111038
111518
|
});
|
|
111039
111519
|
}
|
|
111040
111520
|
for (const frameDir of hdrFrameDirs.values()) {
|
|
111041
|
-
|
|
111521
|
+
clearMaxFrameIndex(frameDir);
|
|
111042
111522
|
}
|
|
111043
111523
|
hdrFrameDirs.clear();
|
|
111044
111524
|
}
|
|
@@ -111310,6 +111790,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111310
111790
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
111311
111791
|
const totalElapsed = Date.now() - pipelineStart;
|
|
111312
111792
|
sampleMemory();
|
|
111793
|
+
const tmpPeakBytes = existsSync16(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
111313
111794
|
const perfSummary = {
|
|
111314
111795
|
renderId: job.id,
|
|
111315
111796
|
totalElapsedMs: totalElapsed,
|
|
@@ -111324,6 +111805,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111324
111805
|
videoCount: composition.videos.length,
|
|
111325
111806
|
audioCount: composition.audios.length,
|
|
111326
111807
|
stages: perfStages,
|
|
111808
|
+
videoExtractBreakdown: extractionResult?.phaseBreakdown,
|
|
111809
|
+
tmpPeakBytes,
|
|
111327
111810
|
hdrDiagnostics: hdrDiagnostics.videoExtractionFailures > 0 || hdrDiagnostics.imageDecodeFailures > 0 ? { ...hdrDiagnostics } : void 0,
|
|
111328
111811
|
captureAvgMs: totalFrames > 0 ? Math.round((perfStages.captureMs ?? 0) / totalFrames) : void 0,
|
|
111329
111812
|
peakRssMb: Math.round(peakRssBytes / (1024 * 1024)),
|
|
@@ -111332,7 +111815,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111332
111815
|
job.perfSummary = perfSummary;
|
|
111333
111816
|
if (job.config.debug) {
|
|
111334
111817
|
try {
|
|
111335
|
-
|
|
111818
|
+
writeFileSync5(perfOutputPath, JSON.stringify(perfSummary, null, 2), "utf-8");
|
|
111336
111819
|
} catch (err) {
|
|
111337
111820
|
log.debug("Failed to write perf summary", {
|
|
111338
111821
|
perfOutputPath,
|
|
@@ -111341,8 +111824,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111341
111824
|
}
|
|
111342
111825
|
}
|
|
111343
111826
|
if (job.config.debug) {
|
|
111344
|
-
if (
|
|
111345
|
-
const debugOutput =
|
|
111827
|
+
if (existsSync16(outputPath)) {
|
|
111828
|
+
const debugOutput = join16(workDir, `output${videoExt}`);
|
|
111346
111829
|
copyFileSync2(outputPath, debugOutput);
|
|
111347
111830
|
}
|
|
111348
111831
|
} else if (process.env.KEEP_TEMP === "1") {
|
|
@@ -111428,7 +111911,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111428
111911
|
await safeCleanup(
|
|
111429
111912
|
"remove workDir (error)",
|
|
111430
111913
|
() => {
|
|
111431
|
-
if (
|
|
111914
|
+
if (existsSync16(workDir)) rmSync3(workDir, { recursive: true, force: true });
|
|
111432
111915
|
},
|
|
111433
111916
|
log
|
|
111434
111917
|
);
|
|
@@ -111441,8 +111924,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
111441
111924
|
}
|
|
111442
111925
|
|
|
111443
111926
|
// src/services/hyperframeLint.ts
|
|
111444
|
-
import { existsSync as
|
|
111445
|
-
import { resolve as resolve12, join as
|
|
111927
|
+
import { existsSync as existsSync17, readFileSync as readFileSync11, statSync as statSync8 } from "node:fs";
|
|
111928
|
+
import { resolve as resolve12, join as join17 } from "node:path";
|
|
111446
111929
|
function isStringRecord(value) {
|
|
111447
111930
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
111448
111931
|
return false;
|
|
@@ -111470,7 +111953,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
111470
111953
|
}
|
|
111471
111954
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
111472
111955
|
const absProjectDir = resolve12(projectDir);
|
|
111473
|
-
if (!
|
|
111956
|
+
if (!existsSync17(absProjectDir) || !statSync8(absProjectDir).isDirectory()) {
|
|
111474
111957
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111475
111958
|
}
|
|
111476
111959
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -111481,7 +111964,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111481
111964
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
111482
111965
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
111483
111966
|
}
|
|
111484
|
-
if (
|
|
111967
|
+
if (existsSync17(absoluteEntryPath) && statSync8(absoluteEntryPath).isFile()) {
|
|
111485
111968
|
return {
|
|
111486
111969
|
entryFile,
|
|
111487
111970
|
html: readFileSync11(absoluteEntryPath, "utf-8"),
|
|
@@ -111490,7 +111973,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
111490
111973
|
}
|
|
111491
111974
|
}
|
|
111492
111975
|
return {
|
|
111493
|
-
error: `No HTML entry file found in project directory: ${
|
|
111976
|
+
error: `No HTML entry file found in project directory: ${join17(absProjectDir, preferredEntryFile || "index.html")}`
|
|
111494
111977
|
};
|
|
111495
111978
|
}
|
|
111496
111979
|
function prepareHyperframeLintBody(body) {
|
|
@@ -111581,11 +112064,11 @@ async function prepareRenderBody(body) {
|
|
|
111581
112064
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
111582
112065
|
if (projectDir) {
|
|
111583
112066
|
const absProjectDir = resolve13(projectDir);
|
|
111584
|
-
if (!
|
|
112067
|
+
if (!existsSync18(absProjectDir) || !statSync9(absProjectDir).isDirectory()) {
|
|
111585
112068
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
111586
112069
|
}
|
|
111587
112070
|
const entry = options.entryFile || "index.html";
|
|
111588
|
-
if (!
|
|
112071
|
+
if (!existsSync18(resolve13(absProjectDir, entry))) {
|
|
111589
112072
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
111590
112073
|
}
|
|
111591
112074
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -111610,8 +112093,8 @@ async function prepareRenderBody(body) {
|
|
|
111610
112093
|
}
|
|
111611
112094
|
}
|
|
111612
112095
|
const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir2();
|
|
111613
|
-
const tempProjectDir = mkdtempSync(
|
|
111614
|
-
|
|
112096
|
+
const tempProjectDir = mkdtempSync(join18(tempRoot, "producer-project-"));
|
|
112097
|
+
writeFileSync6(join18(tempProjectDir, "index.html"), htmlContent, "utf-8");
|
|
111615
112098
|
return {
|
|
111616
112099
|
prepared: {
|
|
111617
112100
|
input: {
|
|
@@ -111734,7 +112217,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111734
112217
|
log
|
|
111735
112218
|
);
|
|
111736
112219
|
const outputDir = dirname11(absoluteOutputPath);
|
|
111737
|
-
if (!
|
|
112220
|
+
if (!existsSync18(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
111738
112221
|
const release = await renderSemaphore.acquire();
|
|
111739
112222
|
log.info("render started", {
|
|
111740
112223
|
requestId,
|
|
@@ -111761,7 +112244,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111761
112244
|
log.info(`render progress ${pct}%`, { requestId, stage: j.currentStage, message });
|
|
111762
112245
|
}
|
|
111763
112246
|
});
|
|
111764
|
-
const fileSize =
|
|
112247
|
+
const fileSize = existsSync18(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
111765
112248
|
const durationMs = Date.now() - t0;
|
|
111766
112249
|
const outputToken = store.register(absoluteOutputPath);
|
|
111767
112250
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -111845,7 +112328,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111845
112328
|
log
|
|
111846
112329
|
);
|
|
111847
112330
|
const outputDir = dirname11(absoluteOutputPath);
|
|
111848
|
-
if (!
|
|
112331
|
+
if (!existsSync18(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
111849
112332
|
log.info("render-stream started", { requestId, projectDir: input2.projectDir });
|
|
111850
112333
|
const job = createRenderJob({
|
|
111851
112334
|
fps: input2.fps,
|
|
@@ -111890,7 +112373,7 @@ function createRenderHandlers(options = {}) {
|
|
|
111890
112373
|
},
|
|
111891
112374
|
abortController.signal
|
|
111892
112375
|
);
|
|
111893
|
-
const fileSize =
|
|
112376
|
+
const fileSize = existsSync18(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
111894
112377
|
const outputToken = store.register(absoluteOutputPath);
|
|
111895
112378
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
111896
112379
|
log.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -111949,11 +112432,11 @@ function createRenderHandlers(options = {}) {
|
|
|
111949
112432
|
if (!artifact) {
|
|
111950
112433
|
return c.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
111951
112434
|
}
|
|
111952
|
-
if (!
|
|
112435
|
+
if (!existsSync18(artifact.path)) {
|
|
111953
112436
|
store.delete(token);
|
|
111954
112437
|
return c.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
111955
112438
|
}
|
|
111956
|
-
const stats =
|
|
112439
|
+
const stats = statSync9(artifact.path);
|
|
111957
112440
|
return new Response(createReadStream2(artifact.path), {
|
|
111958
112441
|
headers: {
|
|
111959
112442
|
"content-type": "video/mp4",
|