@hyperframes/producer 0.8.207 → 0.8.209
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/distributed.js +99 -52
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +67 -67
- package/dist/index.js +99 -52
- package/dist/public-server.js +13 -8
- package/dist/services/distributed/renderChunk.d.ts +2 -0
- package/dist/services/render/stages/captureStage.d.ts +1 -0
- package/dist/services/render/stages/extractVideosStage.d.ts +1 -1
- package/dist/services/renderOrchestrator.d.ts +1 -0
- package/package.json +7 -7
package/dist/distributed.js
CHANGED
|
@@ -794,7 +794,7 @@ function createFileServer(options) {
|
|
|
794
794
|
if (!streamOwnsFd) closeSync(fd);
|
|
795
795
|
}
|
|
796
796
|
});
|
|
797
|
-
return new Promise((resolve10) => {
|
|
797
|
+
return new Promise((resolve10, reject) => {
|
|
798
798
|
const connections = /* @__PURE__ */ new Set();
|
|
799
799
|
const server = serve({ fetch: app.fetch, port, hostname: "127.0.0.1" }, (info) => {
|
|
800
800
|
resolve10({
|
|
@@ -814,6 +814,7 @@ function createFileServer(options) {
|
|
|
814
814
|
connections.add(socket);
|
|
815
815
|
socket.on("close", () => connections.delete(socket));
|
|
816
816
|
});
|
|
817
|
+
server.on("error", reject);
|
|
817
818
|
});
|
|
818
819
|
}
|
|
819
820
|
|
|
@@ -1858,7 +1859,7 @@ import { gsapCdnDist, normalizeGsapBaseUrl } from "@hyperframes/core/gsap-cdn";
|
|
|
1858
1859
|
import {
|
|
1859
1860
|
assignBundledRuntimeCompositionIds,
|
|
1860
1861
|
assignMediaRenderIds,
|
|
1861
|
-
|
|
1862
|
+
emitVariablesByCompScript,
|
|
1862
1863
|
inlineSubCompositions as inlineSubCompositionsShared,
|
|
1863
1864
|
ensureExternalLinkTag,
|
|
1864
1865
|
ensureExternalScriptTag,
|
|
@@ -3430,9 +3431,9 @@ function inlineSubCompositions(html, subCompositions, projectDir, variableOverri
|
|
|
3430
3431
|
}
|
|
3431
3432
|
}
|
|
3432
3433
|
}
|
|
3433
|
-
|
|
3434
|
+
emitVariablesByCompScript(document2, result.variablesByComp);
|
|
3434
3435
|
if (body) {
|
|
3435
|
-
let pending =
|
|
3436
|
+
let pending = [];
|
|
3436
3437
|
const flushInline = () => {
|
|
3437
3438
|
if (!pending.length) return;
|
|
3438
3439
|
const joined = pending.join("\n;\n");
|
|
@@ -5446,10 +5447,11 @@ var VideoExtractionStageError = class extends Error {
|
|
|
5446
5447
|
kind: failure.kind,
|
|
5447
5448
|
affectedElementCount: failure.count
|
|
5448
5449
|
}))
|
|
5449
|
-
)) {
|
|
5450
|
+
), ffmpegReason) {
|
|
5450
5451
|
const total = failures.reduce((sum2, failure) => sum2 + failure.count, 0);
|
|
5451
5452
|
const breakdown = failures.map((failure) => `${failure.kind}=${failure.count}`).join(",");
|
|
5452
|
-
|
|
5453
|
+
const reason = ffmpegReason ? `: ffmpeg said: ${ffmpegReason}` : "";
|
|
5454
|
+
super(`Video extraction failed for ${total} source(s) [${code}; ${breakdown}]${reason}`);
|
|
5453
5455
|
this.code = code;
|
|
5454
5456
|
this.retryable = retryable;
|
|
5455
5457
|
this.failures = failures;
|
|
@@ -5496,7 +5498,8 @@ function buildVideoExtractionStageError(result) {
|
|
|
5496
5498
|
retryable ? "VIDEO_EXTRACTION_FAILED" : "VIDEO_SOURCE_UNRENDERABLE",
|
|
5497
5499
|
retryable,
|
|
5498
5500
|
failures,
|
|
5499
|
-
extractionFailureMetadataFromResult(result)
|
|
5501
|
+
extractionFailureMetadataFromResult(result),
|
|
5502
|
+
result.errors.find((failure) => failure.ffmpegReason)?.ffmpegReason
|
|
5500
5503
|
);
|
|
5501
5504
|
}
|
|
5502
5505
|
function buildHdrProbeStageError(failures) {
|
|
@@ -6501,6 +6504,7 @@ async function runCaptureStage(input) {
|
|
|
6501
6504
|
dedupPerfs,
|
|
6502
6505
|
pageErrorLines: workerPageErrors,
|
|
6503
6506
|
openAttempt: input.openAttempt,
|
|
6507
|
+
verifyFirstSession: input.verifyFirstSession,
|
|
6504
6508
|
onProgress: (progress) => {
|
|
6505
6509
|
if (progress.latestWorkerPhase) {
|
|
6506
6510
|
if (progress.capturedFrames === 0) reportWorkerStartup(job, progress, onProgress);
|
|
@@ -7371,7 +7375,8 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
7371
7375
|
});
|
|
7372
7376
|
} : void 0,
|
|
7373
7377
|
void 0,
|
|
7374
|
-
options.cfg
|
|
7378
|
+
options.cfg,
|
|
7379
|
+
{ verifyFirstSession: options.verifyFirstSession }
|
|
7375
7380
|
);
|
|
7376
7381
|
pushWorkerDedupPerfs(workerResults, options.dedupPerfs);
|
|
7377
7382
|
if (options.pageErrorLines) pushWorkerPageErrors(workerResults, options.pageErrorLines);
|
|
@@ -11432,16 +11437,18 @@ function observedChunkCaptureMode(perfs) {
|
|
|
11432
11437
|
}
|
|
11433
11438
|
return mode;
|
|
11434
11439
|
}
|
|
11440
|
+
var PROBE_SELECTED_SCREENSHOT = "[renderChunk] probe selected screenshot capture";
|
|
11435
11441
|
function shouldRetryChunkCaptureWithScreenshot(error) {
|
|
11436
11442
|
const failure = classifyCaptureFailure4(error);
|
|
11437
11443
|
if (failure.kind === "cancelled" || failure.kind === "memory_exhaustion") return false;
|
|
11438
|
-
return /HeadlessExperimental\.beginFrame/i.test(failure.message) || /beginFrame probe timeout/i.test(failure.message) || /Another frame is pending|Frame still pending/i.test(failure.message);
|
|
11444
|
+
return /HeadlessExperimental\.beginFrame/i.test(failure.message) || /beginFrame probe timeout/i.test(failure.message) || failure.message.includes(PROBE_SELECTED_SCREENSHOT) || /Another frame is pending|Frame still pending/i.test(failure.message);
|
|
11439
11445
|
}
|
|
11440
11446
|
async function runCaptureWithScreenshotFallback(input) {
|
|
11441
11447
|
try {
|
|
11442
11448
|
return await input.run(input.forceScreenshot);
|
|
11443
11449
|
} catch (error) {
|
|
11444
|
-
if (input.forceScreenshot ||
|
|
11450
|
+
if (input.forceScreenshot || await input.canRetry?.() === false) throw error;
|
|
11451
|
+
if (!shouldRetryChunkCaptureWithScreenshot(error)) throw error;
|
|
11445
11452
|
input.onFallback?.(error);
|
|
11446
11453
|
await input.resetForScreenshotRetry();
|
|
11447
11454
|
return await input.run(true);
|
|
@@ -11650,7 +11657,24 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11650
11657
|
let extraction;
|
|
11651
11658
|
const overlap = { current: null };
|
|
11652
11659
|
try {
|
|
11653
|
-
|
|
11660
|
+
const verifyInWorker = chunkWorkerCount > 1 && !forceScreenshotForChunk;
|
|
11661
|
+
let boxesMeasured;
|
|
11662
|
+
let boxesFailed;
|
|
11663
|
+
const boxesReady = new Promise((resolve10, reject) => {
|
|
11664
|
+
boxesMeasured = resolve10;
|
|
11665
|
+
boxesFailed = reject;
|
|
11666
|
+
});
|
|
11667
|
+
boxesReady.catch(() => {
|
|
11668
|
+
});
|
|
11669
|
+
const measureBoxes = async (page) => {
|
|
11670
|
+
shownBoxes = await measureVideoShownBoxes(
|
|
11671
|
+
page,
|
|
11672
|
+
[...shownFrames.keys()],
|
|
11673
|
+
chunkFrameNumbers.map((frame) => frame * chunkFps.den / chunkFps.num)
|
|
11674
|
+
);
|
|
11675
|
+
boxesMeasured();
|
|
11676
|
+
};
|
|
11677
|
+
if (chunkWorkerCount === 1) {
|
|
11654
11678
|
const bootStarted = Date.now();
|
|
11655
11679
|
session = await createVerifiedDistributedCaptureSession(
|
|
11656
11680
|
fileServer.url,
|
|
@@ -11659,11 +11683,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11659
11683
|
cfg
|
|
11660
11684
|
);
|
|
11661
11685
|
sessionBootMs = Date.now() - bootStarted;
|
|
11662
|
-
|
|
11663
|
-
session.page,
|
|
11664
|
-
[...shownFrames.keys()],
|
|
11665
|
-
chunkFrameNumbers.map((frame) => frame * chunkFps.den / chunkFps.num)
|
|
11666
|
-
);
|
|
11686
|
+
await measureBoxes(session.page);
|
|
11667
11687
|
const browserSelectedScreenshot = session.launchCaptureMode === "screenshot";
|
|
11668
11688
|
const beginFrameStalled = !browserSelectedScreenshot && await beginFrameSessionNeedsScreenshotFallback(session);
|
|
11669
11689
|
if (browserSelectedScreenshot) {
|
|
@@ -11672,10 +11692,6 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11672
11692
|
"[renderChunk] Browser capability probe selected screenshot capture for the entire chunk",
|
|
11673
11693
|
{ chunkIndex }
|
|
11674
11694
|
);
|
|
11675
|
-
if (chunkWorkerCount > 1) {
|
|
11676
|
-
await closeCaptureSession10(session);
|
|
11677
|
-
session = null;
|
|
11678
|
-
}
|
|
11679
11695
|
} else if (beginFrameStalled) {
|
|
11680
11696
|
forceScreenshotForChunk = true;
|
|
11681
11697
|
log.warn(
|
|
@@ -11685,41 +11701,66 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11685
11701
|
await closeCaptureSession10(session).catch(() => {
|
|
11686
11702
|
});
|
|
11687
11703
|
session = null;
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
|
|
11698
|
-
|
|
11699
|
-
|
|
11704
|
+
const screenshotBootStarted = Date.now();
|
|
11705
|
+
const screenshotCfg = {
|
|
11706
|
+
...cfg,
|
|
11707
|
+
forceScreenshot: true,
|
|
11708
|
+
forceScreenshotExplicitlyOptedOut: false
|
|
11709
|
+
};
|
|
11710
|
+
session = await createVerifiedDistributedCaptureSession(
|
|
11711
|
+
fileServer.url,
|
|
11712
|
+
framesDir,
|
|
11713
|
+
captureOptions,
|
|
11714
|
+
screenshotCfg
|
|
11715
|
+
);
|
|
11716
|
+
sessionBootMs += Date.now() - screenshotBootStarted;
|
|
11717
|
+
}
|
|
11718
|
+
} else if (!verifyInWorker) {
|
|
11719
|
+
boxesMeasured();
|
|
11720
|
+
}
|
|
11721
|
+
let verification;
|
|
11722
|
+
const verifyFirstWorker = (first) => verification ??= (async () => {
|
|
11723
|
+
sessionBootMs = Date.now() - verifyStarted;
|
|
11724
|
+
try {
|
|
11725
|
+
await measureBoxes(first.page);
|
|
11726
|
+
const selectedScreenshot = first.launchCaptureMode === "screenshot";
|
|
11727
|
+
if (selectedScreenshot || await beginFrameSessionNeedsScreenshotFallback(first)) {
|
|
11728
|
+
forceScreenshotForChunk = true;
|
|
11729
|
+
log.warn(
|
|
11730
|
+
selectedScreenshot ? "[renderChunk] Browser capability probe selected screenshot capture for the entire chunk" : "[renderChunk] BeginFrame liveness probe failed; using screenshot capture for the entire chunk",
|
|
11731
|
+
{ chunkIndex }
|
|
11700
11732
|
);
|
|
11701
|
-
|
|
11733
|
+
throw new Error(PROBE_SELECTED_SCREENSHOT);
|
|
11702
11734
|
}
|
|
11703
|
-
}
|
|
11704
|
-
|
|
11705
|
-
|
|
11735
|
+
} catch (error) {
|
|
11736
|
+
if (!forceScreenshotForChunk) {
|
|
11737
|
+
verifyFailure = error;
|
|
11738
|
+
boxesFailed(error);
|
|
11739
|
+
}
|
|
11740
|
+
throw error;
|
|
11706
11741
|
}
|
|
11707
|
-
}
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11742
|
+
})();
|
|
11743
|
+
let verifyStarted = 0;
|
|
11744
|
+
let verifyFailure;
|
|
11745
|
+
const deferredVideoFrames = planVideos ? boxesReady.then(() => {
|
|
11746
|
+
const extractStarted = Date.now();
|
|
11747
|
+
return extractDeferredVideoFramesForChunk({
|
|
11748
|
+
planDir,
|
|
11749
|
+
planVideos,
|
|
11750
|
+
frames: chunkFrameNumbers,
|
|
11751
|
+
fps: chunkFps,
|
|
11752
|
+
outputRoot: videoFramesDir,
|
|
11753
|
+
cfg,
|
|
11754
|
+
remoteSources,
|
|
11755
|
+
shownBoxes
|
|
11756
|
+
}).then((frames) => {
|
|
11757
|
+
videoExtractMs = Date.now() - extractStarted;
|
|
11758
|
+
return frames;
|
|
11759
|
+
});
|
|
11760
|
+
}) : boxesReady.then(() => []);
|
|
11722
11761
|
extraction = deferredVideoFrames;
|
|
11762
|
+
deferredVideoFrames.catch(() => {
|
|
11763
|
+
});
|
|
11723
11764
|
const videoFrameLookup = planVideos && planVideos.extracted.length > 0 ? deferredVideoFrames.then(
|
|
11724
11765
|
(deferred) => createFrameLookupTable5(
|
|
11725
11766
|
planVideos.videos,
|
|
@@ -11798,6 +11839,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11798
11839
|
const captureStarted = Date.now();
|
|
11799
11840
|
captureMode = await runCaptureWithScreenshotFallback({
|
|
11800
11841
|
forceScreenshot: forceScreenshotForChunk,
|
|
11842
|
+
canRetry: () => verifyFailure === void 0,
|
|
11801
11843
|
// fallow-ignore-next-line complexity
|
|
11802
11844
|
run: async (forceScreenshot) => {
|
|
11803
11845
|
const captureCfg = cfg.forceScreenshot === forceScreenshot ? cfg : {
|
|
@@ -11827,6 +11869,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11827
11869
|
}
|
|
11828
11870
|
const captureSession = session;
|
|
11829
11871
|
session = null;
|
|
11872
|
+
verifyStarted = Date.now();
|
|
11830
11873
|
overlap.current = canEncodeWhileCapturing(encodeInput, chunkWorkerCount, cpus().length) ? encodeWhileCapturing(encodeInput, framesInChunk) : null;
|
|
11831
11874
|
await observeRenderStage(
|
|
11832
11875
|
new RenderObservabilityRecorder({ pipelineStartMs: start, log }),
|
|
@@ -11854,7 +11897,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11854
11897
|
frameRange: range,
|
|
11855
11898
|
onFrameLanded: (frame) => overlap.current?.onFrameLanded(frame),
|
|
11856
11899
|
interleaveFrames: interleavesCapture(overlap.current !== null, options),
|
|
11857
|
-
openAttempt
|
|
11900
|
+
openAttempt,
|
|
11901
|
+
verifyFirstSession: forceScreenshot || !verifyInWorker ? void 0 : verifyFirstWorker
|
|
11858
11902
|
}),
|
|
11859
11903
|
{ stall: frameStallRule(job) }
|
|
11860
11904
|
).catch(async (captureError) => {
|
|
@@ -11866,6 +11910,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11866
11910
|
},
|
|
11867
11911
|
resetForScreenshotRetry: () => {
|
|
11868
11912
|
rmSync11(workDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
11913
|
+
boxesMeasured();
|
|
11869
11914
|
mkdirSync14(framesDir, { recursive: true });
|
|
11870
11915
|
capturePerfs.length = 0;
|
|
11871
11916
|
captureAttempts.length = 0;
|
|
@@ -11881,6 +11926,8 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath, options) {
|
|
|
11881
11926
|
);
|
|
11882
11927
|
}
|
|
11883
11928
|
}).catch(async (captureError) => {
|
|
11929
|
+
if (verifyFailure !== void 0) throw verifyFailure;
|
|
11930
|
+
boxesFailed(captureError);
|
|
11884
11931
|
await deferredVideoFrames;
|
|
11885
11932
|
throw captureError;
|
|
11886
11933
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"buildId": "dev",
|
|
4
|
-
"sha256": "
|
|
4
|
+
"sha256": "d294fc169f5c0e16d5272a816ae4f0fd6e78a652c61fd6939c882c9bee81efeb",
|
|
5
5
|
"artifacts": {
|
|
6
6
|
"iife": "hyperframe.runtime.iife.js",
|
|
7
7
|
"esm": "hyperframe.runtime.mjs"
|