@hyperframes/engine 0.9.20 → 0.9.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.
|
@@ -1002,7 +1002,7 @@ export async function assertWebGpuAdapterAvailable(page, requiresWebGpu, softwar
|
|
|
1002
1002
|
return await Promise.race([
|
|
1003
1003
|
probe(),
|
|
1004
1004
|
new Promise((resolve) => {
|
|
1005
|
-
timer = setTimeout(() => {
|
|
1005
|
+
timer = (globalThis.window?.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(() => {
|
|
1006
1006
|
expired = true;
|
|
1007
1007
|
resolve(false);
|
|
1008
1008
|
}, timeoutMs);
|
|
@@ -488,7 +488,7 @@ syncToPaintEvent = true) {
|
|
|
488
488
|
}
|
|
489
489
|
// Encode OUTSIDE the paint handler — heavy canvas work inside the
|
|
490
490
|
// paint event can stall the renderer.
|
|
491
|
-
setTimeout(() => {
|
|
491
|
+
(window.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(() => {
|
|
492
492
|
try {
|
|
493
493
|
resolveCapture(fmt === "png"
|
|
494
494
|
? canvas.toDataURL("image/png")
|
|
@@ -520,7 +520,7 @@ syncToPaintEvent = true) {
|
|
|
520
520
|
// throttled page), fall back to an unsynchronized draw after 250 ms —
|
|
521
521
|
// worst case one-frame-stale content (the root's alpha may lag its
|
|
522
522
|
// transform by that frame) rather than a hung render.
|
|
523
|
-
setTimeout(() => {
|
|
523
|
+
(window.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(() => {
|
|
524
524
|
canvas.removeEventListener("paint", onPaint);
|
|
525
525
|
drawAndEncode();
|
|
526
526
|
}, 250);
|
|
@@ -870,7 +870,7 @@ export async function produceDrawElementFrame(page, width, height, quality = 80,
|
|
|
870
870
|
// Sentinel dirty + requestPaint() — see __hfDeInvalidate in
|
|
871
871
|
// injectDrawElementCanvas.
|
|
872
872
|
usedRequestPaint = aw.__hfDeInvalidate?.() === true;
|
|
873
|
-
setTimeout(() => {
|
|
873
|
+
(window.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(() => {
|
|
874
874
|
canvas.removeEventListener("paint", onPaint);
|
|
875
875
|
drawAndKick();
|
|
876
876
|
}, 250);
|
|
@@ -957,7 +957,7 @@ export async function produceDrawElementFrameBatch(page, times, width, height, q
|
|
|
957
957
|
// Sentinel dirty + requestPaint() — see __hfDeInvalidate in
|
|
958
958
|
// injectDrawElementCanvas.
|
|
959
959
|
usedRequestPaint = aw.__hfDeInvalidate?.() === true;
|
|
960
|
-
setTimeout(settle, 250);
|
|
960
|
+
(window.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(settle, 250);
|
|
961
961
|
});
|
|
962
962
|
let prevBitmap = Promise.resolve();
|
|
963
963
|
let prevBitmapIdx = -1;
|
|
@@ -418,7 +418,7 @@ export declare function formatConsoleDiagnostic(type: string, text: string, loca
|
|
|
418
418
|
text: string;
|
|
419
419
|
suppressHostLog: boolean;
|
|
420
420
|
};
|
|
421
|
-
export declare const HF_READY_DIAGNOSTIC_EXPR = "(async function() {\n var hf = window.__hf;\n var player = window.__player;\n var renderReady = !!window.__renderReady;\n var hasSeek = !!(hf && typeof hf.seek === \"function\");\n var duration = hf ? hf.duration : -1;\n var hasTimeline = !!(window.__timelines && Object.keys(window.__timelines).length > 0);\n var root = document.querySelector(\"[data-composition-id]\");\n var declaredDuration = root ? Number(root.getAttribute(\"data-duration\")) : -1;\n var registry = (window.__hf && window.__hf.buildReady) || {};\n var keys = Object.keys(registry);\n // A microtask race mis-sorts a non-native thenable (extra adoption tick)\n // and rejects the whole expression on a rejected entry. Settling each\n // key onto its own record and waiting one macrotask avoids both.\n var settled = {};\n if (keys.length > 0) {\n keys.forEach(function(key) {\n Promise.resolve(registry[key]).then(\n function() { settled[key] = \"resolved\"; },\n function() { settled[key] = \"rejected\"; },\n );\n });\n await new Promise(function(r) { setTimeout(r, 0)
|
|
421
|
+
export declare const HF_READY_DIAGNOSTIC_EXPR = "(async function() {\n var hf = window.__hf;\n var player = window.__player;\n var renderReady = !!window.__renderReady;\n var hasSeek = !!(hf && typeof hf.seek === \"function\");\n var duration = hf ? hf.duration : -1;\n var hasTimeline = !!(window.__timelines && Object.keys(window.__timelines).length > 0);\n var root = document.querySelector(\"[data-composition-id]\");\n var declaredDuration = root ? Number(root.getAttribute(\"data-duration\")) : -1;\n var registry = (window.__hf && window.__hf.buildReady) || {};\n var keys = Object.keys(registry);\n // A microtask race mis-sorts a non-native thenable (extra adoption tick)\n // and rejects the whole expression on a rejected entry. Settling each\n // key onto its own record and waiting one macrotask avoids both.\n var settled = {};\n if (keys.length > 0) {\n keys.forEach(function(key) {\n Promise.resolve(registry[key]).then(\n function() { settled[key] = \"resolved\"; },\n function() { settled[key] = \"rejected\"; },\n );\n });\n await new Promise(function(r) {\n (window.__HF_VIRTUAL_TIME__ && window.__HF_VIRTUAL_TIME__.originalSetTimeout || setTimeout)(r, 0);\n });\n }\n // A thenable resolving via its own setTimeout(0) can still misreport as\n // pending here (macrotask registration order, not resolution order), a\n // narrow case that self-corrects on the next ~1s diagnostic tick.\n var pendingBuildReadyKeys = keys.filter(function(key) { return !settled[key]; });\n var rejectedBuildReadyKeys = keys.filter(function(key) { return settled[key] === \"rejected\"; });\n return {\n renderReady: renderReady,\n hasHf: !!hf,\n hasSeek: hasSeek,\n hasPlayer: !!player,\n duration: duration,\n hasTimeline: hasTimeline,\n declaredDuration: declaredDuration,\n pendingBuildReadyKeys: pendingBuildReadyKeys,\n rejectedBuildReadyKeys: rejectedBuildReadyKeys,\n };\n})()";
|
|
422
422
|
export interface HfDiagnostic {
|
|
423
423
|
renderReady: boolean;
|
|
424
424
|
hasHf: boolean;
|
|
@@ -163,7 +163,7 @@ export async function decodeDynamicCssBackgroundImages(page) {
|
|
|
163
163
|
image.src = url;
|
|
164
164
|
let timer;
|
|
165
165
|
const expired = new Promise((resolve) => {
|
|
166
|
-
timer = setTimeout(() => resolve("late"), limitMs);
|
|
166
|
+
timer = (window.__HF_VIRTUAL_TIME__?.originalSetTimeout ?? setTimeout)(() => resolve("late"), limitMs);
|
|
167
167
|
});
|
|
168
168
|
try {
|
|
169
169
|
const outcome = await Promise.race([
|
|
@@ -1208,7 +1208,9 @@ export const HF_READY_DIAGNOSTIC_EXPR = `(async function() {
|
|
|
1208
1208
|
function() { settled[key] = "rejected"; },
|
|
1209
1209
|
);
|
|
1210
1210
|
});
|
|
1211
|
-
await new Promise(function(r) {
|
|
1211
|
+
await new Promise(function(r) {
|
|
1212
|
+
(window.__HF_VIRTUAL_TIME__ && window.__HF_VIRTUAL_TIME__.originalSetTimeout || setTimeout)(r, 0);
|
|
1213
|
+
});
|
|
1212
1214
|
}
|
|
1213
1215
|
// A thenable resolving via its own setTimeout(0) can still misreport as
|
|
1214
1216
|
// pending here (macrotask registration order, not resolution order), a
|
|
@@ -506,9 +506,20 @@ export function parseImageElements(html) {
|
|
|
506
506
|
return images;
|
|
507
507
|
}
|
|
508
508
|
const firstFrameColourCache = new Map();
|
|
509
|
-
/** A source's SPS transfers,
|
|
509
|
+
/** A source's SPS transfers, read as the trace streams (a run keeps only stderr's tail); null when the read failed. */
|
|
510
510
|
function readKeyframeTransfers(videoPath, codec) {
|
|
511
|
-
|
|
511
|
+
let traced = "";
|
|
512
|
+
let rest = "";
|
|
513
|
+
const onStderr = (chunk) => {
|
|
514
|
+
const lines = (rest + chunk).split("\n");
|
|
515
|
+
rest = lines.pop() ?? "";
|
|
516
|
+
for (const line of lines)
|
|
517
|
+
if (line.includes("transfer_characteristics"))
|
|
518
|
+
traced += `${line}\n`;
|
|
519
|
+
};
|
|
520
|
+
return inExtractionSlot(() => runFfmpeg([...urlInputArgs(videoPath), ...keyframeTransferArgs(videoPath, codec)], {
|
|
521
|
+
onStderr,
|
|
522
|
+
})).then((result) => (result.success ? parseKeyframeTransfers(traced + rest) : null));
|
|
512
523
|
}
|
|
513
524
|
/** The first shown frame's colour tags (see {@link firstFrameColourArgs}), probed once per source file. */
|
|
514
525
|
function readFirstFrameColour(videoPath, codec) {
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/engine",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"description": "Seekable web page to video rendering engine (Puppeteer + FFmpeg)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"puppeteer": "~25.11.0",
|
|
62
62
|
"puppeteer-core": "^25.11.0",
|
|
63
63
|
"undici": "7.25.0",
|
|
64
|
-
"@hyperframes/
|
|
65
|
-
"@hyperframes/
|
|
64
|
+
"@hyperframes/core": "^0.9.22",
|
|
65
|
+
"@hyperframes/parsers": "^0.9.22"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^25.0.10",
|