hyperframes 0.4.11-alpha.1 → 0.4.12
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/cli.js +416 -95
- package/dist/hyperframe-runtime.js +5 -5
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +5 -5
- package/dist/studio/assets/hyperframes-player-5iD9BZnx.js +198 -0
- package/dist/studio/assets/{index-FSgUtn41.js → index-CVDXfFQ6.js} +1 -1
- package/dist/studio/index.html +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/hyperframes-player-Zx0MOyMy.js +0 -198
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.4.
|
|
57
|
+
VERSION = true ? "0.4.12" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -5199,7 +5199,9 @@ function readConfig() {
|
|
|
5199
5199
|
telemetryNoticeShown: parsed.telemetryNoticeShown ?? DEFAULT_CONFIG.telemetryNoticeShown,
|
|
5200
5200
|
commandCount: parsed.commandCount ?? DEFAULT_CONFIG.commandCount,
|
|
5201
5201
|
lastUpdateCheck: parsed.lastUpdateCheck,
|
|
5202
|
-
latestVersion: parsed.latestVersion
|
|
5202
|
+
latestVersion: parsed.latestVersion,
|
|
5203
|
+
pendingUpdate: parsed.pendingUpdate,
|
|
5204
|
+
completedUpdate: parsed.completedUpdate
|
|
5203
5205
|
};
|
|
5204
5206
|
cachedConfig = config;
|
|
5205
5207
|
return { ...config };
|
|
@@ -5429,8 +5431,8 @@ function flushSync() {
|
|
|
5429
5431
|
eventQueue = [];
|
|
5430
5432
|
const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch });
|
|
5431
5433
|
try {
|
|
5432
|
-
const { spawn:
|
|
5433
|
-
const child =
|
|
5434
|
+
const { spawn: spawn13 } = __require("child_process");
|
|
5435
|
+
const child = spawn13(
|
|
5434
5436
|
process.execPath,
|
|
5435
5437
|
[
|
|
5436
5438
|
"-e",
|
|
@@ -20492,7 +20494,7 @@ var init_config2 = __esm({
|
|
|
20492
20494
|
ffmpegStreamingTimeout: 6e5,
|
|
20493
20495
|
hdr: false,
|
|
20494
20496
|
hdrAutoDetect: true,
|
|
20495
|
-
audioGain: 1
|
|
20497
|
+
audioGain: 1,
|
|
20496
20498
|
frameDataUriCacheLimit: 256,
|
|
20497
20499
|
playerReadyTimeout: 45e3,
|
|
20498
20500
|
renderReadyTimeout: 15e3,
|
|
@@ -22729,6 +22731,37 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config) {
|
|
|
22729
22731
|
);
|
|
22730
22732
|
}
|
|
22731
22733
|
}
|
|
22734
|
+
async function convertVfrToCfr(inputPath, outputPath, targetFps, startTime, duration, signal, config) {
|
|
22735
|
+
const timeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
22736
|
+
const args = [
|
|
22737
|
+
"-ss",
|
|
22738
|
+
String(startTime),
|
|
22739
|
+
"-i",
|
|
22740
|
+
inputPath,
|
|
22741
|
+
"-t",
|
|
22742
|
+
String(duration),
|
|
22743
|
+
"-fps_mode",
|
|
22744
|
+
"cfr",
|
|
22745
|
+
"-r",
|
|
22746
|
+
String(targetFps),
|
|
22747
|
+
"-c:v",
|
|
22748
|
+
"libx264",
|
|
22749
|
+
"-preset",
|
|
22750
|
+
"fast",
|
|
22751
|
+
"-crf",
|
|
22752
|
+
"18",
|
|
22753
|
+
"-c:a",
|
|
22754
|
+
"copy",
|
|
22755
|
+
"-y",
|
|
22756
|
+
outputPath
|
|
22757
|
+
];
|
|
22758
|
+
const result = await runFfmpeg(args, { signal, timeout });
|
|
22759
|
+
if (!result.success) {
|
|
22760
|
+
throw new Error(
|
|
22761
|
+
`VFR\u2192CFR conversion failed (exit ${result.exitCode}): ${result.stderr.slice(-300)}`
|
|
22762
|
+
);
|
|
22763
|
+
}
|
|
22764
|
+
}
|
|
22732
22765
|
async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
|
|
22733
22766
|
const startTime = Date.now();
|
|
22734
22767
|
const extracted = [];
|
|
@@ -22786,6 +22819,39 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
22786
22819
|
}
|
|
22787
22820
|
}
|
|
22788
22821
|
}
|
|
22822
|
+
const vfrNormDir = join21(options.outputDir, "_vfr_normalized");
|
|
22823
|
+
for (let i2 = 0; i2 < resolvedVideos.length; i2++) {
|
|
22824
|
+
if (signal?.aborted) break;
|
|
22825
|
+
const entry = resolvedVideos[i2];
|
|
22826
|
+
if (!entry) continue;
|
|
22827
|
+
const metadata = await extractVideoMetadata(entry.videoPath);
|
|
22828
|
+
if (!metadata.isVFR) continue;
|
|
22829
|
+
let segDuration = entry.video.end - entry.video.start;
|
|
22830
|
+
if (!Number.isFinite(segDuration) || segDuration <= 0) {
|
|
22831
|
+
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
22832
|
+
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
22833
|
+
}
|
|
22834
|
+
mkdirSync12(vfrNormDir, { recursive: true });
|
|
22835
|
+
const normalizedPath = join21(vfrNormDir, `${entry.video.id}_cfr.mp4`);
|
|
22836
|
+
try {
|
|
22837
|
+
await convertVfrToCfr(
|
|
22838
|
+
entry.videoPath,
|
|
22839
|
+
normalizedPath,
|
|
22840
|
+
options.fps,
|
|
22841
|
+
entry.video.mediaStart,
|
|
22842
|
+
segDuration,
|
|
22843
|
+
signal,
|
|
22844
|
+
config
|
|
22845
|
+
);
|
|
22846
|
+
entry.videoPath = normalizedPath;
|
|
22847
|
+
entry.video = { ...entry.video, mediaStart: 0 };
|
|
22848
|
+
} catch (err) {
|
|
22849
|
+
errors.push({
|
|
22850
|
+
videoId: entry.video.id,
|
|
22851
|
+
error: err instanceof Error ? err.message : String(err)
|
|
22852
|
+
});
|
|
22853
|
+
}
|
|
22854
|
+
}
|
|
22789
22855
|
const results = await Promise.all(
|
|
22790
22856
|
resolvedVideos.map(async ({ video, videoPath }) => {
|
|
22791
22857
|
if (signal?.aborted) {
|
|
@@ -23546,7 +23612,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
23546
23612
|
end: element.end,
|
|
23547
23613
|
mediaStart: element.mediaStart,
|
|
23548
23614
|
duration: element.end - element.start,
|
|
23549
|
-
volume: element.volume
|
|
23615
|
+
volume: element.volume ?? 1
|
|
23550
23616
|
});
|
|
23551
23617
|
} catch (err) {
|
|
23552
23618
|
errors.push(`Error: ${element.id} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -27658,8 +27724,8 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
27658
27724
|
);
|
|
27659
27725
|
}
|
|
27660
27726
|
if (metadata.isVFR) {
|
|
27661
|
-
console.
|
|
27662
|
-
`[Compiler]
|
|
27727
|
+
console.info(
|
|
27728
|
+
`[Compiler] Video "${video.id}" is variable frame rate (VFR); the engine will normalize it to CFR before frame extraction. If rendering feels slow on this video, pre-encode once with: ${reencode}`
|
|
27663
27729
|
);
|
|
27664
27730
|
}
|
|
27665
27731
|
}).catch(() => {
|
|
@@ -27857,11 +27923,11 @@ import { join as join31, dirname as dirname10, resolve as resolve15 } from "path
|
|
|
27857
27923
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
27858
27924
|
import { freemem as freemem2 } from "os";
|
|
27859
27925
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
27860
|
-
async function safeCleanup(label2, fn,
|
|
27926
|
+
async function safeCleanup(label2, fn, log2 = defaultLogger) {
|
|
27861
27927
|
try {
|
|
27862
27928
|
await fn();
|
|
27863
27929
|
} catch (err) {
|
|
27864
|
-
|
|
27930
|
+
log2.debug(`Cleanup failed (${label2})`, {
|
|
27865
27931
|
error: err instanceof Error ? err.message : String(err)
|
|
27866
27932
|
});
|
|
27867
27933
|
}
|
|
@@ -27889,7 +27955,7 @@ function updateJobStatus(job, status, stage, progress, onProgress) {
|
|
|
27889
27955
|
if (status === "failed" || status === "complete") job.completedAt = /* @__PURE__ */ new Date();
|
|
27890
27956
|
if (onProgress) onProgress(job, stage);
|
|
27891
27957
|
}
|
|
27892
|
-
function installDebugLogger(logPath,
|
|
27958
|
+
function installDebugLogger(logPath, log2 = defaultLogger) {
|
|
27893
27959
|
const origLog = console.log;
|
|
27894
27960
|
const origError = console.error;
|
|
27895
27961
|
const origWarn = console.warn;
|
|
@@ -27900,7 +27966,7 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
27900
27966
|
try {
|
|
27901
27967
|
appendFileSync(logPath, line);
|
|
27902
27968
|
} catch (err) {
|
|
27903
|
-
|
|
27969
|
+
log2.debug("Debug log write failed", {
|
|
27904
27970
|
logPath,
|
|
27905
27971
|
error: err instanceof Error ? err.message : String(err)
|
|
27906
27972
|
});
|
|
@@ -27967,15 +28033,15 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
27967
28033
|
writeFileSync10(join31(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
27968
28034
|
}
|
|
27969
28035
|
}
|
|
27970
|
-
function applyRenderModeHints(cfg, compiled,
|
|
28036
|
+
function applyRenderModeHints(cfg, compiled, log2 = defaultLogger) {
|
|
27971
28037
|
if (cfg.forceScreenshot || !compiled.renderModeHints.recommendScreenshot) return;
|
|
27972
28038
|
cfg.forceScreenshot = true;
|
|
27973
|
-
|
|
28039
|
+
log2.warn("Auto-selected screenshot capture mode for render compatibility", {
|
|
27974
28040
|
reasonCodes: compiled.renderModeHints.reasons.map((reason) => reason.code),
|
|
27975
28041
|
reasons: compiled.renderModeHints.reasons.map((reason) => reason.message)
|
|
27976
28042
|
});
|
|
27977
28043
|
}
|
|
27978
|
-
function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, width, height,
|
|
28044
|
+
function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, width, height, log2, sourceTransfer, targetTransfer) {
|
|
27979
28045
|
const frameDir = hdrFrameDirs.get(el.id);
|
|
27980
28046
|
const startTime = hdrStartTimes.get(el.id);
|
|
27981
28047
|
if (!frameDir || startTime === void 0) {
|
|
@@ -28025,14 +28091,14 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
28025
28091
|
);
|
|
28026
28092
|
}
|
|
28027
28093
|
} catch (err) {
|
|
28028
|
-
if (
|
|
28029
|
-
|
|
28094
|
+
if (log2) {
|
|
28095
|
+
log2.debug(`HDR blit failed for ${el.id}`, {
|
|
28030
28096
|
error: err instanceof Error ? err.message : String(err)
|
|
28031
28097
|
});
|
|
28032
28098
|
}
|
|
28033
28099
|
}
|
|
28034
28100
|
}
|
|
28035
|
-
function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height,
|
|
28101
|
+
function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log2, sourceTransfer, targetTransfer) {
|
|
28036
28102
|
const buf = hdrImageBuffers.get(el.id);
|
|
28037
28103
|
if (!buf) {
|
|
28038
28104
|
return;
|
|
@@ -28074,8 +28140,8 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
|
|
|
28074
28140
|
);
|
|
28075
28141
|
}
|
|
28076
28142
|
} catch (err) {
|
|
28077
|
-
if (
|
|
28078
|
-
|
|
28143
|
+
if (log2) {
|
|
28144
|
+
log2.debug(`HDR image blit failed for ${el.id}`, {
|
|
28079
28145
|
error: err instanceof Error ? err.message : String(err)
|
|
28080
28146
|
});
|
|
28081
28147
|
}
|
|
@@ -28126,7 +28192,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28126
28192
|
const debugDir = join31(producerRoot, ".debug");
|
|
28127
28193
|
const workDir = job.config.debug ? join31(debugDir, job.id) : join31(dirname10(outputPath), `work-${job.id}`);
|
|
28128
28194
|
const pipelineStart = Date.now();
|
|
28129
|
-
const
|
|
28195
|
+
const log2 = job.config.logger ?? defaultLogger;
|
|
28130
28196
|
let fileServer = null;
|
|
28131
28197
|
let probeSession = null;
|
|
28132
28198
|
let lastBrowserConsole = [];
|
|
@@ -28159,7 +28225,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28159
28225
|
if (!existsSync28(workDir)) mkdirSync17(workDir, { recursive: true });
|
|
28160
28226
|
if (job.config.debug) {
|
|
28161
28227
|
const logPath = join31(workDir, "render.log");
|
|
28162
|
-
restoreLogger = installDebugLogger(logPath,
|
|
28228
|
+
restoreLogger = installDebugLogger(logPath, log2);
|
|
28163
28229
|
}
|
|
28164
28230
|
const entryFile = job.config.entryFile || "index.html";
|
|
28165
28231
|
let htmlPath = join31(projectDir, entryFile);
|
|
@@ -28187,7 +28253,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28187
28253
|
}
|
|
28188
28254
|
writeFileSync10(wrapperPath, standaloneHtml, "utf-8");
|
|
28189
28255
|
htmlPath = wrapperPath;
|
|
28190
|
-
|
|
28256
|
+
log2.info("Extracted standalone entry from index.html host context", {
|
|
28191
28257
|
entryFile
|
|
28192
28258
|
});
|
|
28193
28259
|
}
|
|
@@ -28197,9 +28263,9 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28197
28263
|
let compiled = await compileForRender(projectDir, htmlPath, join31(workDir, "downloads"));
|
|
28198
28264
|
assertNotAborted();
|
|
28199
28265
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
28200
|
-
applyRenderModeHints(cfg, compiled,
|
|
28266
|
+
applyRenderModeHints(cfg, compiled, log2);
|
|
28201
28267
|
writeCompiledArtifacts(compiled, workDir, Boolean(job.config.debug));
|
|
28202
|
-
|
|
28268
|
+
log2.info("Compiled composition metadata", {
|
|
28203
28269
|
entryFile,
|
|
28204
28270
|
staticDuration: compiled.staticDuration,
|
|
28205
28271
|
width: compiled.width,
|
|
@@ -28251,13 +28317,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28251
28317
|
if (composition.duration <= 0) {
|
|
28252
28318
|
const discoveredDuration = await getCompositionDuration(probeSession);
|
|
28253
28319
|
assertNotAborted();
|
|
28254
|
-
|
|
28320
|
+
log2.info("Probed composition duration from browser", {
|
|
28255
28321
|
discoveredDuration,
|
|
28256
28322
|
staticDuration: compiled.staticDuration
|
|
28257
28323
|
});
|
|
28258
28324
|
composition.duration = discoveredDuration;
|
|
28259
28325
|
} else {
|
|
28260
|
-
|
|
28326
|
+
log2.info("Using static duration from data-duration attribute", {
|
|
28261
28327
|
duration: composition.duration
|
|
28262
28328
|
});
|
|
28263
28329
|
}
|
|
@@ -28387,7 +28453,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28387
28453
|
}
|
|
28388
28454
|
}
|
|
28389
28455
|
} catch (err) {
|
|
28390
|
-
|
|
28456
|
+
log2.warn("Failed to gather browser diagnostics for zero-duration composition", {
|
|
28391
28457
|
error: err instanceof Error ? err.message : String(err)
|
|
28392
28458
|
});
|
|
28393
28459
|
diagnostics.push("(Could not gather browser diagnostics \u2014 page may have crashed)");
|
|
@@ -28400,7 +28466,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28400
28466
|
(line) => /404|ERR_NAME_NOT_RESOLVED|ERR_CONNECTION_REFUSED|net::ERR_/i.test(line)
|
|
28401
28467
|
);
|
|
28402
28468
|
if (failedRequests.length > 0) {
|
|
28403
|
-
|
|
28469
|
+
log2.warn("Browser encountered network failures during page load:", {
|
|
28404
28470
|
failures: failedRequests.slice(0, 10)
|
|
28405
28471
|
});
|
|
28406
28472
|
for (const line of failedRequests.slice(0, 5)) {
|
|
@@ -28507,13 +28573,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28507
28573
|
}
|
|
28508
28574
|
}
|
|
28509
28575
|
if (effectiveHdr && outputFormat !== "mp4") {
|
|
28510
|
-
|
|
28576
|
+
log2.warn(
|
|
28511
28577
|
`[Render] HDR source detected but format is ${outputFormat} \u2014 falling back to SDR. Use --format mp4 for HDR10 output.`
|
|
28512
28578
|
);
|
|
28513
28579
|
effectiveHdr = void 0;
|
|
28514
28580
|
}
|
|
28515
28581
|
if (effectiveHdr) {
|
|
28516
|
-
|
|
28582
|
+
log2.info(
|
|
28517
28583
|
`[Render] HDR source detected \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
|
|
28518
28584
|
);
|
|
28519
28585
|
}
|
|
@@ -28568,7 +28634,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28568
28634
|
const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
|
|
28569
28635
|
job.framesRendered = 0;
|
|
28570
28636
|
if (hasHdrContent) {
|
|
28571
|
-
|
|
28637
|
+
log2.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
|
|
28572
28638
|
cfg.forceScreenshot = true;
|
|
28573
28639
|
const hdrVideoIds = composition.videos.filter((v) => nativeHdrVideoIds.has(v.id)).map((v) => v.id);
|
|
28574
28640
|
const hdrVideoSrcPaths = /* @__PURE__ */ new Map();
|
|
@@ -28611,7 +28677,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28611
28677
|
endFrame: Math.ceil((t3.time + t3.duration) * job.config.fps)
|
|
28612
28678
|
}));
|
|
28613
28679
|
if (transitionRanges.length > 0) {
|
|
28614
|
-
|
|
28680
|
+
log2.info("[Render] Detected shader transitions for HDR compositing", {
|
|
28615
28681
|
count: transitionRanges.length,
|
|
28616
28682
|
transitions: transitionRanges.map((t3) => ({
|
|
28617
28683
|
shader: t3.shader,
|
|
@@ -28704,7 +28770,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28704
28770
|
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
28705
28771
|
if (!result.success) {
|
|
28706
28772
|
hdrDiagnostics.videoExtractionFailures += 1;
|
|
28707
|
-
|
|
28773
|
+
log2.error("HDR frame pre-extraction failed; aborting render", {
|
|
28708
28774
|
videoId,
|
|
28709
28775
|
srcPath,
|
|
28710
28776
|
stderr: result.stderr.slice(-400)
|
|
@@ -28746,7 +28812,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28746
28812
|
}
|
|
28747
28813
|
} catch (err) {
|
|
28748
28814
|
hdrDiagnostics.imageDecodeFailures += 1;
|
|
28749
|
-
|
|
28815
|
+
log2.error("HDR image decode failed; aborting render", {
|
|
28750
28816
|
imageId,
|
|
28751
28817
|
srcPath,
|
|
28752
28818
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -28790,7 +28856,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28790
28856
|
const layers = groupIntoLayers(filteredStacking);
|
|
28791
28857
|
const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
|
|
28792
28858
|
if (shouldLog) {
|
|
28793
|
-
|
|
28859
|
+
log2.info("[diag] compositeToBuffer plan", {
|
|
28794
28860
|
frame: debugFrameIndex,
|
|
28795
28861
|
time: time.toFixed(3),
|
|
28796
28862
|
filterSize: elementFilter?.size,
|
|
@@ -28821,7 +28887,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28821
28887
|
hdrImageBuffers,
|
|
28822
28888
|
width,
|
|
28823
28889
|
height,
|
|
28824
|
-
|
|
28890
|
+
log2,
|
|
28825
28891
|
imageTransfers.get(layer.element.id),
|
|
28826
28892
|
effectiveHdr?.transfer
|
|
28827
28893
|
);
|
|
@@ -28835,7 +28901,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28835
28901
|
hdrVideoStartTimes,
|
|
28836
28902
|
width,
|
|
28837
28903
|
height,
|
|
28838
|
-
|
|
28904
|
+
log2,
|
|
28839
28905
|
videoTransfers.get(layer.element.id),
|
|
28840
28906
|
effectiveHdr?.transfer
|
|
28841
28907
|
);
|
|
@@ -28844,7 +28910,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28844
28910
|
const after2 = countNonZeroRgb482(canvas);
|
|
28845
28911
|
if (isHdrImage) {
|
|
28846
28912
|
const buf = hdrImageBuffers.get(layer.element.id);
|
|
28847
|
-
|
|
28913
|
+
log2.info("[diag] hdr layer blit", {
|
|
28848
28914
|
frame: debugFrameIndex,
|
|
28849
28915
|
layerIdx,
|
|
28850
28916
|
id: layer.element.id,
|
|
@@ -28860,7 +28926,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28860
28926
|
const localTime = time - startTime;
|
|
28861
28927
|
const frameNum = Math.floor(localTime * job.config.fps) + 1;
|
|
28862
28928
|
const expectedFrame = frameDir ? join31(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
28863
|
-
|
|
28929
|
+
log2.info("[diag] hdr layer blit", {
|
|
28864
28930
|
frame: debugFrameIndex,
|
|
28865
28931
|
layerIdx,
|
|
28866
28932
|
id: layer.element.id,
|
|
@@ -28903,7 +28969,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28903
28969
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
28904
28970
|
const dumpPath = join31(debugDumpDir, dumpName);
|
|
28905
28971
|
writeFileSync10(dumpPath, domPng);
|
|
28906
|
-
|
|
28972
|
+
log2.info("[diag] dom layer blit", {
|
|
28907
28973
|
frame: debugFrameIndex,
|
|
28908
28974
|
layerIdx,
|
|
28909
28975
|
layerIds: layer.elementIds,
|
|
@@ -28916,7 +28982,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28916
28982
|
});
|
|
28917
28983
|
}
|
|
28918
28984
|
} catch (err) {
|
|
28919
|
-
|
|
28985
|
+
log2.warn("DOM layer decode/blit failed; skipping overlay", {
|
|
28920
28986
|
layerIds: layer.elementIds,
|
|
28921
28987
|
error: err instanceof Error ? err.message : String(err)
|
|
28922
28988
|
});
|
|
@@ -28925,7 +28991,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28925
28991
|
}
|
|
28926
28992
|
if (shouldLog && debugDumpDir) {
|
|
28927
28993
|
const finalNonZero = countNonZeroRgb482(canvas);
|
|
28928
|
-
|
|
28994
|
+
log2.info("[diag] compositeToBuffer end", {
|
|
28929
28995
|
frame: debugFrameIndex,
|
|
28930
28996
|
finalNonZeroPixels: finalNonZero,
|
|
28931
28997
|
totalPixels: width * height,
|
|
@@ -28954,7 +29020,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28954
29020
|
);
|
|
28955
29021
|
if (i2 % 30 === 0) {
|
|
28956
29022
|
const hdrEl = stackingInfo.find((e2) => e2.isHdr);
|
|
28957
|
-
|
|
29023
|
+
log2.debug("[Render] HDR layer composite frame", {
|
|
28958
29024
|
frame: i2,
|
|
28959
29025
|
time: time.toFixed(2),
|
|
28960
29026
|
hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
|
|
@@ -28987,7 +29053,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
28987
29053
|
hdrImageBuffers,
|
|
28988
29054
|
width,
|
|
28989
29055
|
height,
|
|
28990
|
-
|
|
29056
|
+
log2,
|
|
28991
29057
|
imageTransfers.get(el.id),
|
|
28992
29058
|
effectiveHdr?.transfer
|
|
28993
29059
|
);
|
|
@@ -29001,7 +29067,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29001
29067
|
hdrVideoStartTimes,
|
|
29002
29068
|
width,
|
|
29003
29069
|
height,
|
|
29004
|
-
|
|
29070
|
+
log2,
|
|
29005
29071
|
videoTransfers.get(el.id),
|
|
29006
29072
|
effectiveHdr?.transfer
|
|
29007
29073
|
);
|
|
@@ -29027,7 +29093,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29027
29093
|
effectiveHdr.transfer
|
|
29028
29094
|
);
|
|
29029
29095
|
} catch (err) {
|
|
29030
|
-
|
|
29096
|
+
log2.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
|
|
29031
29097
|
frameIndex: i2,
|
|
29032
29098
|
sceneIds: Array.from(sceneIds),
|
|
29033
29099
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -29059,7 +29125,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29059
29125
|
try {
|
|
29060
29126
|
rmSync6(frameDir, { recursive: true, force: true });
|
|
29061
29127
|
} catch (err) {
|
|
29062
|
-
|
|
29128
|
+
log2.warn("Failed to clean up HDR frame directory", {
|
|
29063
29129
|
videoId,
|
|
29064
29130
|
frameDir,
|
|
29065
29131
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -29367,7 +29433,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29367
29433
|
try {
|
|
29368
29434
|
writeFileSync10(perfOutputPath, JSON.stringify(perfSummary, null, 2), "utf-8");
|
|
29369
29435
|
} catch (err) {
|
|
29370
|
-
|
|
29436
|
+
log2.debug("Failed to write perf summary", {
|
|
29371
29437
|
perfOutputPath,
|
|
29372
29438
|
error: err instanceof Error ? err.message : String(err)
|
|
29373
29439
|
});
|
|
@@ -29379,14 +29445,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29379
29445
|
copyFileSync2(outputPath, debugOutput);
|
|
29380
29446
|
}
|
|
29381
29447
|
} else if (process.env.KEEP_TEMP === "1") {
|
|
29382
|
-
|
|
29448
|
+
log2.info("KEEP_TEMP=1 \u2014 leaving workDir on disk for inspection", { workDir });
|
|
29383
29449
|
} else {
|
|
29384
29450
|
await safeCleanup(
|
|
29385
29451
|
"remove workDir",
|
|
29386
29452
|
() => {
|
|
29387
29453
|
rmSync6(workDir, { recursive: true, force: true });
|
|
29388
29454
|
},
|
|
29389
|
-
|
|
29455
|
+
log2
|
|
29390
29456
|
);
|
|
29391
29457
|
}
|
|
29392
29458
|
if (restoreLogger) restoreLogger();
|
|
@@ -29401,12 +29467,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29401
29467
|
() => {
|
|
29402
29468
|
fs4.close();
|
|
29403
29469
|
},
|
|
29404
|
-
|
|
29470
|
+
log2
|
|
29405
29471
|
);
|
|
29406
29472
|
}
|
|
29407
29473
|
if (probeSession) {
|
|
29408
29474
|
const session = probeSession;
|
|
29409
|
-
await safeCleanup("close probe session (cancel)", () => closeCaptureSession(session),
|
|
29475
|
+
await safeCleanup("close probe session (cancel)", () => closeCaptureSession(session), log2);
|
|
29410
29476
|
}
|
|
29411
29477
|
if (!job.config.debug) {
|
|
29412
29478
|
await safeCleanup(
|
|
@@ -29414,7 +29480,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29414
29480
|
() => {
|
|
29415
29481
|
rmSync6(workDir, { recursive: true, force: true });
|
|
29416
29482
|
},
|
|
29417
|
-
|
|
29483
|
+
log2
|
|
29418
29484
|
);
|
|
29419
29485
|
}
|
|
29420
29486
|
if (restoreLogger) restoreLogger();
|
|
@@ -29425,7 +29491,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29425
29491
|
const isTimeoutError = errorMessage.includes("Waiting failed") || errorMessage.includes("timeout exceeded") || errorMessage.includes("Navigation timeout");
|
|
29426
29492
|
const wasParallel = job.config.workers !== 1;
|
|
29427
29493
|
if (isTimeoutError && wasParallel) {
|
|
29428
|
-
|
|
29494
|
+
log2.warn(
|
|
29429
29495
|
`Parallel capture timed out with ${job.config.workers ?? "auto"} workers. Video-heavy compositions often need sequential capture. Retry with --workers 1`
|
|
29430
29496
|
);
|
|
29431
29497
|
}
|
|
@@ -29450,12 +29516,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29450
29516
|
() => {
|
|
29451
29517
|
fs4.close();
|
|
29452
29518
|
},
|
|
29453
|
-
|
|
29519
|
+
log2
|
|
29454
29520
|
);
|
|
29455
29521
|
}
|
|
29456
29522
|
if (probeSession) {
|
|
29457
29523
|
const session = probeSession;
|
|
29458
|
-
await safeCleanup("close probe session (error)", () => closeCaptureSession(session),
|
|
29524
|
+
await safeCleanup("close probe session (error)", () => closeCaptureSession(session), log2);
|
|
29459
29525
|
}
|
|
29460
29526
|
if (!job.config.debug) {
|
|
29461
29527
|
await safeCleanup(
|
|
@@ -29463,7 +29529,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
29463
29529
|
() => {
|
|
29464
29530
|
if (existsSync28(workDir)) rmSync6(workDir, { recursive: true, force: true });
|
|
29465
29531
|
},
|
|
29466
|
-
|
|
29532
|
+
log2
|
|
29467
29533
|
);
|
|
29468
29534
|
}
|
|
29469
29535
|
if (restoreLogger) restoreLogger();
|
|
@@ -29727,12 +29793,12 @@ async function prepareRenderBody(body) {
|
|
|
29727
29793
|
}
|
|
29728
29794
|
};
|
|
29729
29795
|
}
|
|
29730
|
-
function resolveOutputPath(projectDir, outputCandidate, rendersDir,
|
|
29796
|
+
function resolveOutputPath(projectDir, outputCandidate, rendersDir, log2) {
|
|
29731
29797
|
try {
|
|
29732
29798
|
return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
|
|
29733
29799
|
} catch (error) {
|
|
29734
29800
|
const fallbackPath = resolve17(rendersDir, `producer-fallback-${Date.now()}.mp4`);
|
|
29735
|
-
|
|
29801
|
+
log2.warn("Failed to resolve output path, using fallback", {
|
|
29736
29802
|
fallback: fallbackPath,
|
|
29737
29803
|
error: error instanceof Error ? error.message : String(error)
|
|
29738
29804
|
});
|
|
@@ -29764,19 +29830,19 @@ function createArtifactStore(ttlMs) {
|
|
|
29764
29830
|
}
|
|
29765
29831
|
};
|
|
29766
29832
|
}
|
|
29767
|
-
function cleanupTempDir(dir,
|
|
29833
|
+
function cleanupTempDir(dir, log2) {
|
|
29768
29834
|
if (!dir) return;
|
|
29769
29835
|
try {
|
|
29770
29836
|
rmSync7(dir, { recursive: true, force: true });
|
|
29771
29837
|
} catch (error) {
|
|
29772
|
-
|
|
29838
|
+
log2.warn("Failed to cleanup temp project dir", {
|
|
29773
29839
|
cleanupProjectDir: dir,
|
|
29774
29840
|
error: error instanceof Error ? error.message : String(error)
|
|
29775
29841
|
});
|
|
29776
29842
|
}
|
|
29777
29843
|
}
|
|
29778
29844
|
function createRenderHandlers(options = {}) {
|
|
29779
|
-
const
|
|
29845
|
+
const log2 = options.logger ?? defaultLogger;
|
|
29780
29846
|
const getRequestId = options.getRequestId ?? ((c2) => c2.req.header("x-request-id") || crypto2.randomUUID());
|
|
29781
29847
|
const outputUrlPrefix = options.outputUrlPrefix ?? "/outputs";
|
|
29782
29848
|
const rendersDir = options.rendersDir ?? process.env.PRODUCER_RENDERS_DIR ?? "/tmp";
|
|
@@ -29803,7 +29869,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29803
29869
|
return c2.json({ success: false, requestId, error: preparedResult.error }, 400);
|
|
29804
29870
|
}
|
|
29805
29871
|
const result = runHyperframeLint(preparedResult.prepared);
|
|
29806
|
-
|
|
29872
|
+
log2.info("lint completed", {
|
|
29807
29873
|
requestId,
|
|
29808
29874
|
entryFile: preparedResult.prepared.entryFile,
|
|
29809
29875
|
source: preparedResult.prepared.source,
|
|
@@ -29836,12 +29902,12 @@ function createRenderHandlers(options = {}) {
|
|
|
29836
29902
|
input.projectDir,
|
|
29837
29903
|
input.outputPath,
|
|
29838
29904
|
rendersDir,
|
|
29839
|
-
|
|
29905
|
+
log2
|
|
29840
29906
|
);
|
|
29841
29907
|
const outputDir = dirname11(absoluteOutputPath);
|
|
29842
29908
|
if (!existsSync30(outputDir)) mkdirSync18(outputDir, { recursive: true });
|
|
29843
29909
|
const release2 = await renderSemaphore.acquire();
|
|
29844
|
-
|
|
29910
|
+
log2.info("render started", {
|
|
29845
29911
|
requestId,
|
|
29846
29912
|
projectDir: input.projectDir,
|
|
29847
29913
|
fps: input.fps,
|
|
@@ -29855,7 +29921,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29855
29921
|
useGpu: input.useGpu,
|
|
29856
29922
|
debug: input.debug,
|
|
29857
29923
|
entryFile: input.entryFile,
|
|
29858
|
-
logger:
|
|
29924
|
+
logger: log2
|
|
29859
29925
|
});
|
|
29860
29926
|
let lastLoggedPct = -10;
|
|
29861
29927
|
try {
|
|
@@ -29863,14 +29929,14 @@ function createRenderHandlers(options = {}) {
|
|
|
29863
29929
|
const pct = Math.floor(j2.progress * 100);
|
|
29864
29930
|
if (pct >= lastLoggedPct + 10) {
|
|
29865
29931
|
lastLoggedPct = pct;
|
|
29866
|
-
|
|
29932
|
+
log2.info(`render progress ${pct}%`, { requestId, stage: j2.currentStage, message });
|
|
29867
29933
|
}
|
|
29868
29934
|
});
|
|
29869
29935
|
const fileSize = existsSync30(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
29870
29936
|
const durationMs = Date.now() - t0;
|
|
29871
29937
|
const outputToken = store.register(absoluteOutputPath);
|
|
29872
29938
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
29873
|
-
|
|
29939
|
+
log2.info("render completed", {
|
|
29874
29940
|
requestId,
|
|
29875
29941
|
durationMs,
|
|
29876
29942
|
fileSize,
|
|
@@ -29890,7 +29956,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29890
29956
|
} catch (error) {
|
|
29891
29957
|
const durationMs = Date.now() - t0;
|
|
29892
29958
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
29893
|
-
|
|
29959
|
+
log2.error("render failed", {
|
|
29894
29960
|
requestId,
|
|
29895
29961
|
durationMs,
|
|
29896
29962
|
error: errorMsg,
|
|
@@ -29909,7 +29975,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29909
29975
|
);
|
|
29910
29976
|
} finally {
|
|
29911
29977
|
release2();
|
|
29912
|
-
cleanupTempDir(cleanupProjectDir,
|
|
29978
|
+
cleanupTempDir(cleanupProjectDir, log2);
|
|
29913
29979
|
}
|
|
29914
29980
|
};
|
|
29915
29981
|
const renderStream = (c2) => {
|
|
@@ -29947,11 +30013,11 @@ function createRenderHandlers(options = {}) {
|
|
|
29947
30013
|
input.projectDir,
|
|
29948
30014
|
input.outputPath,
|
|
29949
30015
|
rendersDir,
|
|
29950
|
-
|
|
30016
|
+
log2
|
|
29951
30017
|
);
|
|
29952
30018
|
const outputDir = dirname11(absoluteOutputPath);
|
|
29953
30019
|
if (!existsSync30(outputDir)) mkdirSync18(outputDir, { recursive: true });
|
|
29954
|
-
|
|
30020
|
+
log2.info("render-stream started", { requestId, projectDir: input.projectDir });
|
|
29955
30021
|
const job = createRenderJob({
|
|
29956
30022
|
fps: input.fps,
|
|
29957
30023
|
quality: input.quality,
|
|
@@ -29960,7 +30026,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29960
30026
|
useGpu: input.useGpu,
|
|
29961
30027
|
debug: input.debug,
|
|
29962
30028
|
entryFile: input.entryFile,
|
|
29963
|
-
logger:
|
|
30029
|
+
logger: log2
|
|
29964
30030
|
});
|
|
29965
30031
|
const abortController = new AbortController();
|
|
29966
30032
|
const onRequestAbort = () => abortController.abort(new RenderCancelledError("request_aborted"));
|
|
@@ -29998,7 +30064,7 @@ function createRenderHandlers(options = {}) {
|
|
|
29998
30064
|
const fileSize = existsSync30(absoluteOutputPath) ? statSync9(absoluteOutputPath).size : 0;
|
|
29999
30065
|
const outputToken = store.register(absoluteOutputPath);
|
|
30000
30066
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
30001
|
-
|
|
30067
|
+
log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
30002
30068
|
await stream.writeSSE({
|
|
30003
30069
|
data: JSON.stringify({
|
|
30004
30070
|
type: "complete",
|
|
@@ -30025,7 +30091,7 @@ function createRenderHandlers(options = {}) {
|
|
|
30025
30091
|
}
|
|
30026
30092
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
30027
30093
|
const elapsedMs = Date.now() - t0;
|
|
30028
|
-
|
|
30094
|
+
log2.error("render-stream failed", {
|
|
30029
30095
|
requestId,
|
|
30030
30096
|
elapsedMs,
|
|
30031
30097
|
error: errorMsg,
|
|
@@ -30044,7 +30110,7 @@ function createRenderHandlers(options = {}) {
|
|
|
30044
30110
|
} finally {
|
|
30045
30111
|
release2();
|
|
30046
30112
|
c2.req.raw.signal.removeEventListener("abort", onRequestAbort);
|
|
30047
|
-
cleanupTempDir(cleanupProjectDir,
|
|
30113
|
+
cleanupTempDir(cleanupProjectDir, log2);
|
|
30048
30114
|
}
|
|
30049
30115
|
});
|
|
30050
30116
|
};
|
|
@@ -30087,22 +30153,22 @@ function createProducerApp(options = {}) {
|
|
|
30087
30153
|
}
|
|
30088
30154
|
function startServer(options = {}) {
|
|
30089
30155
|
const port = options.port ?? parseInt(process.env.PRODUCER_PORT ?? "9847", 10);
|
|
30090
|
-
const
|
|
30156
|
+
const log2 = options.logger ?? defaultLogger;
|
|
30091
30157
|
const app = createProducerApp(options);
|
|
30092
30158
|
const server = serve3({ fetch: app.fetch, port }, () => {
|
|
30093
|
-
|
|
30159
|
+
log2.info(`Listening on http://localhost:${port}`);
|
|
30094
30160
|
});
|
|
30095
30161
|
server.setTimeout(0);
|
|
30096
30162
|
server.requestTimeout = 0;
|
|
30097
30163
|
server.keepAliveTimeout = 0;
|
|
30098
30164
|
function shutdown(signal) {
|
|
30099
|
-
|
|
30165
|
+
log2.info(`Received ${signal}, shutting down`);
|
|
30100
30166
|
server.close(() => {
|
|
30101
|
-
|
|
30167
|
+
log2.info("Server closed");
|
|
30102
30168
|
process.exit(0);
|
|
30103
30169
|
});
|
|
30104
30170
|
setTimeout(() => {
|
|
30105
|
-
|
|
30171
|
+
log2.warn("Forced exit after 30s timeout");
|
|
30106
30172
|
process.exit(1);
|
|
30107
30173
|
}, 3e4).unref();
|
|
30108
30174
|
}
|
|
@@ -37824,7 +37890,7 @@ var require_node = __commonJS({
|
|
|
37824
37890
|
var tty = __require("tty");
|
|
37825
37891
|
var util = __require("util");
|
|
37826
37892
|
exports.init = init;
|
|
37827
|
-
exports.log =
|
|
37893
|
+
exports.log = log2;
|
|
37828
37894
|
exports.formatArgs = formatArgs;
|
|
37829
37895
|
exports.save = save;
|
|
37830
37896
|
exports.load = load;
|
|
@@ -37959,7 +38025,7 @@ var require_node = __commonJS({
|
|
|
37959
38025
|
}
|
|
37960
38026
|
return (/* @__PURE__ */ new Date()).toISOString() + " ";
|
|
37961
38027
|
}
|
|
37962
|
-
function
|
|
38028
|
+
function log2(...args) {
|
|
37963
38029
|
return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + "\n");
|
|
37964
38030
|
}
|
|
37965
38031
|
function save(namespaces) {
|
|
@@ -47424,7 +47490,7 @@ var require_logging_utils = __commonJS({
|
|
|
47424
47490
|
exports.getDebugBackend = getDebugBackend;
|
|
47425
47491
|
exports.getStructuredBackend = getStructuredBackend;
|
|
47426
47492
|
exports.setBackend = setBackend;
|
|
47427
|
-
exports.log =
|
|
47493
|
+
exports.log = log2;
|
|
47428
47494
|
var events_1 = __require("events");
|
|
47429
47495
|
var process2 = __importStar(__require("process"));
|
|
47430
47496
|
var util = __importStar(__require("util"));
|
|
@@ -47456,7 +47522,7 @@ var require_logging_utils = __commonJS({
|
|
|
47456
47522
|
this.func.info = (...args) => this.invokeSeverity(LogSeverity.INFO, ...args);
|
|
47457
47523
|
this.func.warn = (...args) => this.invokeSeverity(LogSeverity.WARNING, ...args);
|
|
47458
47524
|
this.func.error = (...args) => this.invokeSeverity(LogSeverity.ERROR, ...args);
|
|
47459
|
-
this.func.sublog = (namespace2) =>
|
|
47525
|
+
this.func.sublog = (namespace2) => log2(namespace2, this.func);
|
|
47460
47526
|
}
|
|
47461
47527
|
invoke(fields, ...args) {
|
|
47462
47528
|
if (this.upstream) {
|
|
@@ -47623,7 +47689,7 @@ var require_logging_utils = __commonJS({
|
|
|
47623
47689
|
cachedBackend = backend;
|
|
47624
47690
|
loggerCache.clear();
|
|
47625
47691
|
}
|
|
47626
|
-
function
|
|
47692
|
+
function log2(namespace, parent) {
|
|
47627
47693
|
if (!cachedBackend) {
|
|
47628
47694
|
const enablesFlag = process2.env[exports.env.nodeEnables];
|
|
47629
47695
|
if (!enablesFlag) {
|
|
@@ -47756,7 +47822,7 @@ var require_src5 = __commonJS({
|
|
|
47756
47822
|
exports.HEADER_NAME = "Metadata-Flavor";
|
|
47757
47823
|
exports.HEADER_VALUE = "Google";
|
|
47758
47824
|
exports.HEADERS = Object.freeze({ [exports.HEADER_NAME]: exports.HEADER_VALUE });
|
|
47759
|
-
var
|
|
47825
|
+
var log2 = logger.log("gcp-metadata");
|
|
47760
47826
|
exports.METADATA_SERVER_DETECTION = Object.freeze({
|
|
47761
47827
|
"assume-present": "don't try to ping the metadata server, but assume it's present",
|
|
47762
47828
|
none: "don't try to ping the metadata server, but don't try to use it either",
|
|
@@ -47819,9 +47885,9 @@ var require_src5 = __commonJS({
|
|
|
47819
47885
|
responseType: "text",
|
|
47820
47886
|
timeout: requestTimeout()
|
|
47821
47887
|
};
|
|
47822
|
-
|
|
47888
|
+
log2.info("instance request %j", req);
|
|
47823
47889
|
const res = await requestMethod(req);
|
|
47824
|
-
|
|
47890
|
+
log2.info("instance metadata is %s", res.data);
|
|
47825
47891
|
const metadataFlavor = res.headers.get(exports.HEADER_NAME);
|
|
47826
47892
|
if (metadataFlavor !== exports.HEADER_VALUE) {
|
|
47827
47893
|
throw new RangeError(`Invalid response from metadata service: incorrect ${exports.HEADER_NAME} header. Expected '${exports.HEADER_VALUE}', got ${metadataFlavor ? `'${metadataFlavor}'` : "no header"}`);
|
|
@@ -78025,8 +78091,8 @@ var init_capture2 = __esm({
|
|
|
78025
78091
|
} catch (err) {
|
|
78026
78092
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
78027
78093
|
try {
|
|
78028
|
-
const { mkdirSync:
|
|
78029
|
-
|
|
78094
|
+
const { mkdirSync: mkdirSync30, writeFileSync: writeFileSync23 } = await import("fs");
|
|
78095
|
+
mkdirSync30(outputDir, { recursive: true });
|
|
78030
78096
|
const isTimeout = /timeout|timed out/i.test(errMsg);
|
|
78031
78097
|
const reason = isTimeout ? "Page navigation timed out \u2014 the site may be blocking headless browsers or requires authentication." : `Capture failed: ${errMsg}`;
|
|
78032
78098
|
writeFileSync23(
|
|
@@ -78093,6 +78159,256 @@ var init_telemetry2 = __esm({
|
|
|
78093
78159
|
}
|
|
78094
78160
|
});
|
|
78095
78161
|
|
|
78162
|
+
// src/utils/installerDetection.ts
|
|
78163
|
+
import { realpathSync } from "fs";
|
|
78164
|
+
import { posix as posix2 } from "path";
|
|
78165
|
+
function resolveEntry() {
|
|
78166
|
+
const entry = process.argv[1];
|
|
78167
|
+
if (!entry) return null;
|
|
78168
|
+
try {
|
|
78169
|
+
return realpathSync(entry);
|
|
78170
|
+
} catch {
|
|
78171
|
+
return entry;
|
|
78172
|
+
}
|
|
78173
|
+
}
|
|
78174
|
+
function normalizePath(path2) {
|
|
78175
|
+
return path2.replaceAll("\\", "/");
|
|
78176
|
+
}
|
|
78177
|
+
function isWorkspaceLink(realEntry) {
|
|
78178
|
+
const normalized = normalizePath(realEntry);
|
|
78179
|
+
return normalized.includes("/packages/cli/");
|
|
78180
|
+
}
|
|
78181
|
+
function isEphemeralExec(realEntry) {
|
|
78182
|
+
const normalized = normalizePath(realEntry);
|
|
78183
|
+
return normalized.includes("/_npx/") || normalized.includes("/.npm/_npx/") || posix2.basename(posix2.dirname(normalized)).startsWith("bunx-");
|
|
78184
|
+
}
|
|
78185
|
+
function isHomebrewInstall(realEntry) {
|
|
78186
|
+
return normalizePath(realEntry).includes("/Cellar/hyperframes/");
|
|
78187
|
+
}
|
|
78188
|
+
function detectInstaller() {
|
|
78189
|
+
const realEntry = resolveEntry();
|
|
78190
|
+
if (!realEntry) {
|
|
78191
|
+
return {
|
|
78192
|
+
kind: "skip",
|
|
78193
|
+
installCommand: () => null,
|
|
78194
|
+
reason: "Could not resolve process entry path"
|
|
78195
|
+
};
|
|
78196
|
+
}
|
|
78197
|
+
const normalizedEntry = normalizePath(realEntry);
|
|
78198
|
+
if (isWorkspaceLink(realEntry)) {
|
|
78199
|
+
return {
|
|
78200
|
+
kind: "skip",
|
|
78201
|
+
installCommand: () => null,
|
|
78202
|
+
reason: "Running from a workspace link (monorepo dev)"
|
|
78203
|
+
};
|
|
78204
|
+
}
|
|
78205
|
+
if (isEphemeralExec(realEntry)) {
|
|
78206
|
+
return {
|
|
78207
|
+
kind: "skip",
|
|
78208
|
+
installCommand: () => null,
|
|
78209
|
+
reason: "Running via ephemeral exec (npx / bunx)"
|
|
78210
|
+
};
|
|
78211
|
+
}
|
|
78212
|
+
if (isHomebrewInstall(realEntry)) {
|
|
78213
|
+
return {
|
|
78214
|
+
kind: "brew",
|
|
78215
|
+
// Updating a brew formula isn't a straight `install`; the formula needs
|
|
78216
|
+
// to have been published. Defer to `brew upgrade` which is a no-op if
|
|
78217
|
+
// the tap hasn't caught up.
|
|
78218
|
+
installCommand: () => "brew upgrade hyperframes",
|
|
78219
|
+
reason: `Homebrew install detected at ${realEntry}`
|
|
78220
|
+
};
|
|
78221
|
+
}
|
|
78222
|
+
if (normalizedEntry.includes("/.bun/")) {
|
|
78223
|
+
return {
|
|
78224
|
+
kind: "bun",
|
|
78225
|
+
installCommand: (version) => `bun add -g hyperframes@${version}`,
|
|
78226
|
+
reason: `bun global install detected at ${realEntry}`
|
|
78227
|
+
};
|
|
78228
|
+
}
|
|
78229
|
+
if (normalizedEntry.includes("/pnpm/global/")) {
|
|
78230
|
+
return {
|
|
78231
|
+
kind: "pnpm",
|
|
78232
|
+
installCommand: (version) => `pnpm add -g hyperframes@${version}`,
|
|
78233
|
+
reason: `pnpm global install detected at ${realEntry}`
|
|
78234
|
+
};
|
|
78235
|
+
}
|
|
78236
|
+
if (normalizedEntry.includes("/lib/node_modules/hyperframes/") || normalizedEntry.includes("/npm/node_modules/hyperframes/")) {
|
|
78237
|
+
return {
|
|
78238
|
+
kind: "npm",
|
|
78239
|
+
installCommand: (version) => `npm install -g hyperframes@${version}`,
|
|
78240
|
+
reason: `npm global install detected at ${realEntry}`
|
|
78241
|
+
};
|
|
78242
|
+
}
|
|
78243
|
+
return {
|
|
78244
|
+
kind: "skip",
|
|
78245
|
+
installCommand: () => null,
|
|
78246
|
+
reason: `Unknown install layout at ${realEntry}`
|
|
78247
|
+
};
|
|
78248
|
+
}
|
|
78249
|
+
var init_installerDetection = __esm({
|
|
78250
|
+
"src/utils/installerDetection.ts"() {
|
|
78251
|
+
"use strict";
|
|
78252
|
+
}
|
|
78253
|
+
});
|
|
78254
|
+
|
|
78255
|
+
// src/utils/autoUpdate.ts
|
|
78256
|
+
var autoUpdate_exports = {};
|
|
78257
|
+
__export(autoUpdate_exports, {
|
|
78258
|
+
reportCompletedUpdate: () => reportCompletedUpdate,
|
|
78259
|
+
scheduleBackgroundInstall: () => scheduleBackgroundInstall
|
|
78260
|
+
});
|
|
78261
|
+
import { spawn as spawn12 } from "child_process";
|
|
78262
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync29, openSync } from "fs";
|
|
78263
|
+
import { homedir as homedir10 } from "os";
|
|
78264
|
+
import { join as join53 } from "path";
|
|
78265
|
+
import { compareVersions as compareVersions2 } from "compare-versions";
|
|
78266
|
+
function isAutoInstallDisabled() {
|
|
78267
|
+
if (isDevMode()) return true;
|
|
78268
|
+
if (process.env["CI"] === "true" || process.env["CI"] === "1") return true;
|
|
78269
|
+
if (process.env["HYPERFRAMES_NO_UPDATE_CHECK"] === "1") return true;
|
|
78270
|
+
if (process.env["HYPERFRAMES_NO_AUTO_INSTALL"] === "1") return true;
|
|
78271
|
+
return false;
|
|
78272
|
+
}
|
|
78273
|
+
function majorOf(version) {
|
|
78274
|
+
const match = /^(\d+)\./.exec(version);
|
|
78275
|
+
return match?.[1] ? Number.parseInt(match[1], 10) : Number.NaN;
|
|
78276
|
+
}
|
|
78277
|
+
function log(line) {
|
|
78278
|
+
try {
|
|
78279
|
+
mkdirSync29(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
78280
|
+
appendFileSync2(LOG_FILE, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
78281
|
+
`, { mode: 384 });
|
|
78282
|
+
} catch {
|
|
78283
|
+
}
|
|
78284
|
+
}
|
|
78285
|
+
function launchDetachedInstall(installCommand, version) {
|
|
78286
|
+
mkdirSync29(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
78287
|
+
const configFile = join53(CONFIG_DIR2, "config.json");
|
|
78288
|
+
const nodeScript = `
|
|
78289
|
+
const { exec } = require("node:child_process");
|
|
78290
|
+
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
78291
|
+
const CFG = ${JSON.stringify(configFile)};
|
|
78292
|
+
const TMP = \`\${CFG}.tmp\`;
|
|
78293
|
+
const VERSION = ${JSON.stringify(version)};
|
|
78294
|
+
const CMD = ${JSON.stringify(installCommand)};
|
|
78295
|
+
exec(CMD, { windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (err, _stdout, stderr) => {
|
|
78296
|
+
let cfg = {};
|
|
78297
|
+
try { cfg = JSON.parse(readFileSync(CFG, "utf-8")); } catch (e) {}
|
|
78298
|
+
cfg.completedUpdate = {
|
|
78299
|
+
version: VERSION,
|
|
78300
|
+
ok: !err,
|
|
78301
|
+
finishedAt: new Date().toISOString(),
|
|
78302
|
+
...(err ? { error: String(stderr || err.message || "install failed").slice(-400) } : {}),
|
|
78303
|
+
};
|
|
78304
|
+
delete cfg.pendingUpdate;
|
|
78305
|
+
try {
|
|
78306
|
+
writeFileSync(TMP, JSON.stringify(cfg, null, 2) + "\\n", { mode: 0o600 });
|
|
78307
|
+
renameSync(TMP, CFG);
|
|
78308
|
+
} catch (e) {}
|
|
78309
|
+
});
|
|
78310
|
+
`;
|
|
78311
|
+
const out = openSync(LOG_FILE, "a", 384);
|
|
78312
|
+
const child = spawn12(process.execPath, ["-e", nodeScript], {
|
|
78313
|
+
detached: true,
|
|
78314
|
+
stdio: ["ignore", out, out],
|
|
78315
|
+
windowsHide: true,
|
|
78316
|
+
env: { ...process.env, HYPERFRAMES_NO_UPDATE_CHECK: "1", HYPERFRAMES_NO_AUTO_INSTALL: "1" }
|
|
78317
|
+
});
|
|
78318
|
+
child.unref();
|
|
78319
|
+
log(`[launch] pid=${child.pid ?? "?"} cmd=${installCommand} version=${version}`);
|
|
78320
|
+
}
|
|
78321
|
+
function scheduleBackgroundInstall(latestVersion, currentVersion) {
|
|
78322
|
+
if (isAutoInstallDisabled()) return false;
|
|
78323
|
+
if (!latestVersion || !currentVersion) return false;
|
|
78324
|
+
let cmp;
|
|
78325
|
+
try {
|
|
78326
|
+
cmp = compareVersions2(latestVersion, currentVersion);
|
|
78327
|
+
} catch {
|
|
78328
|
+
return false;
|
|
78329
|
+
}
|
|
78330
|
+
if (cmp <= 0) return false;
|
|
78331
|
+
const latestMajor = majorOf(latestVersion);
|
|
78332
|
+
const currentMajor = majorOf(currentVersion);
|
|
78333
|
+
if (Number.isFinite(latestMajor) && Number.isFinite(currentMajor) && latestMajor > currentMajor) {
|
|
78334
|
+
log(`[skip] major-bump ${currentVersion} -> ${latestVersion}`);
|
|
78335
|
+
return false;
|
|
78336
|
+
}
|
|
78337
|
+
const installer = detectInstaller();
|
|
78338
|
+
if (installer.kind === "skip") {
|
|
78339
|
+
log(`[skip] ${installer.reason}`);
|
|
78340
|
+
return false;
|
|
78341
|
+
}
|
|
78342
|
+
const installCommand = installer.installCommand(latestVersion);
|
|
78343
|
+
if (!installCommand) return false;
|
|
78344
|
+
const config = readConfig();
|
|
78345
|
+
if (config.pendingUpdate) {
|
|
78346
|
+
const startedAt = Date.parse(config.pendingUpdate.startedAt);
|
|
78347
|
+
const age = Number.isFinite(startedAt) ? Date.now() - startedAt : Number.POSITIVE_INFINITY;
|
|
78348
|
+
if (age < PENDING_TIMEOUT_MS && config.pendingUpdate.version === latestVersion) {
|
|
78349
|
+
return false;
|
|
78350
|
+
}
|
|
78351
|
+
}
|
|
78352
|
+
if (config.completedUpdate && config.completedUpdate.version === latestVersion) {
|
|
78353
|
+
return false;
|
|
78354
|
+
}
|
|
78355
|
+
config.pendingUpdate = {
|
|
78356
|
+
version: latestVersion,
|
|
78357
|
+
command: installCommand,
|
|
78358
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
78359
|
+
};
|
|
78360
|
+
writeConfig(config);
|
|
78361
|
+
try {
|
|
78362
|
+
launchDetachedInstall(installCommand, latestVersion);
|
|
78363
|
+
return true;
|
|
78364
|
+
} catch (err) {
|
|
78365
|
+
log(`[error] spawn failed: ${String(err)}`);
|
|
78366
|
+
const rollback = readConfig();
|
|
78367
|
+
delete rollback.pendingUpdate;
|
|
78368
|
+
writeConfig(rollback);
|
|
78369
|
+
return false;
|
|
78370
|
+
}
|
|
78371
|
+
}
|
|
78372
|
+
function reportCompletedUpdate() {
|
|
78373
|
+
if (process.env["HYPERFRAMES_NO_UPDATE_CHECK"] === "1") return;
|
|
78374
|
+
const config = readConfig();
|
|
78375
|
+
const done = config.completedUpdate;
|
|
78376
|
+
if (!done) return;
|
|
78377
|
+
if (done.ok) {
|
|
78378
|
+
delete config.completedUpdate;
|
|
78379
|
+
writeConfig(config);
|
|
78380
|
+
} else if (!done.reported) {
|
|
78381
|
+
config.completedUpdate = { ...done, reported: true };
|
|
78382
|
+
writeConfig(config);
|
|
78383
|
+
} else {
|
|
78384
|
+
return;
|
|
78385
|
+
}
|
|
78386
|
+
if (!process.stderr.isTTY) return;
|
|
78387
|
+
if (done.ok) {
|
|
78388
|
+
process.stderr.write(` hyperframes auto-updated to v${done.version}
|
|
78389
|
+
|
|
78390
|
+
`);
|
|
78391
|
+
} else if (!done.reported) {
|
|
78392
|
+
process.stderr.write(
|
|
78393
|
+
` hyperframes auto-update to v${done.version} failed. Run \`hyperframes upgrade\` to retry.
|
|
78394
|
+
|
|
78395
|
+
`
|
|
78396
|
+
);
|
|
78397
|
+
}
|
|
78398
|
+
}
|
|
78399
|
+
var CONFIG_DIR2, LOG_FILE, PENDING_TIMEOUT_MS;
|
|
78400
|
+
var init_autoUpdate = __esm({
|
|
78401
|
+
"src/utils/autoUpdate.ts"() {
|
|
78402
|
+
"use strict";
|
|
78403
|
+
init_config();
|
|
78404
|
+
init_env();
|
|
78405
|
+
init_installerDetection();
|
|
78406
|
+
CONFIG_DIR2 = join53(homedir10(), ".hyperframes");
|
|
78407
|
+
LOG_FILE = join53(CONFIG_DIR2, "auto-update.log");
|
|
78408
|
+
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
78409
|
+
}
|
|
78410
|
+
});
|
|
78411
|
+
|
|
78096
78412
|
// import("./commands/**/*.js") in src/help.ts
|
|
78097
78413
|
var globImport_commands_js;
|
|
78098
78414
|
var init_ = __esm({
|
|
@@ -78294,10 +78610,15 @@ if (!isHelp && command !== "telemetry" && command !== "unknown") {
|
|
|
78294
78610
|
});
|
|
78295
78611
|
}
|
|
78296
78612
|
if (!isHelp && !hasJsonFlag && command !== "upgrade") {
|
|
78297
|
-
Promise.resolve().then(() => (
|
|
78613
|
+
Promise.resolve().then(() => (init_autoUpdate(), autoUpdate_exports)).then((mod) => mod.reportCompletedUpdate()).catch(() => {
|
|
78614
|
+
});
|
|
78615
|
+
Promise.resolve().then(() => (init_updateCheck(), updateCheck_exports)).then(async (mod) => {
|
|
78298
78616
|
_printUpdateNotice = mod.printUpdateNotice;
|
|
78299
|
-
mod.checkForUpdate().catch(() =>
|
|
78300
|
-
|
|
78617
|
+
const result = await mod.checkForUpdate().catch(() => null);
|
|
78618
|
+
if (result?.updateAvailable) {
|
|
78619
|
+
const auto = await Promise.resolve().then(() => (init_autoUpdate(), autoUpdate_exports)).catch(() => null);
|
|
78620
|
+
auto?.scheduleBackgroundInstall(result.latest, result.current);
|
|
78621
|
+
}
|
|
78301
78622
|
});
|
|
78302
78623
|
}
|
|
78303
78624
|
process.on("beforeExit", () => {
|