hyperframes 0.8.16 → 0.8.18
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 +456 -352
- package/dist/fontLocalizeCli.js +107 -33
- package/dist/hyperframe-runtime.js +5 -5
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +5 -5
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-iAIHATIw.js → hyperframes-player-DzRNJZAz.js} +1 -1
- package/dist/studio/assets/{index-Cf-mbMRL.js → index-B4qse6wy.js} +1 -1
- package/dist/studio/assets/index-BX3KHhGX.js +71 -0
- package/dist/studio/assets/{index-D8o3ZIo2.js → index-F-PUkOVc.js} +128 -128
- package/dist/studio/assets/{index-YmetcS6L.js → index-SGl0bb71.js} +1 -1
- package/dist/studio/index.d.ts +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +1640 -1282
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
package/dist/fontLocalizeCli.js
CHANGED
|
@@ -50943,16 +50943,6 @@ var init_timingCompiler = __esm({
|
|
|
50943
50943
|
});
|
|
50944
50944
|
|
|
50945
50945
|
// ../core/dist/compiler/mediaRenderIds.js
|
|
50946
|
-
function hasPlayableSource(el) {
|
|
50947
|
-
if (el.getAttribute("src"))
|
|
50948
|
-
return true;
|
|
50949
|
-
const sources = el.querySelectorAll?.("source[src]");
|
|
50950
|
-
if (!sources)
|
|
50951
|
-
return false;
|
|
50952
|
-
for (const _ of sources)
|
|
50953
|
-
return true;
|
|
50954
|
-
return false;
|
|
50955
|
-
}
|
|
50956
50946
|
function uniqueRenderId(baseId, taken) {
|
|
50957
50947
|
if (!taken.has(baseId))
|
|
50958
50948
|
return baseId;
|
|
@@ -50965,8 +50955,6 @@ function assignMediaRenderIds(document2) {
|
|
|
50965
50955
|
const taken = /* @__PURE__ */ new Set();
|
|
50966
50956
|
const pending = [];
|
|
50967
50957
|
for (const el of document2.querySelectorAll(MEDIA_SELECTOR)) {
|
|
50968
|
-
if (!hasPlayableSource(el))
|
|
50969
|
-
continue;
|
|
50970
50958
|
const existing = el.getAttribute(MEDIA_RENDER_ID_ATTR);
|
|
50971
50959
|
if (existing) {
|
|
50972
50960
|
taken.add(existing);
|
|
@@ -58584,11 +58572,12 @@ function recordCaptureWarnings(session, warnings) {
|
|
|
58584
58572
|
function recordSubTimelineWarning(session, timeoutMs) {
|
|
58585
58573
|
if (session.subTimelineWaitOutcome === "ready" || !session.subTimelineWaitOutcome) return;
|
|
58586
58574
|
const scriptFailure = session.subTimelineWaitOutcome === "script_failure";
|
|
58575
|
+
const hasRuntimeErrors = session.scriptLoadFailures.some((f) => f.startsWith("runtime-error:"));
|
|
58587
58576
|
recordCaptureWarnings(session, [
|
|
58588
58577
|
{
|
|
58589
58578
|
code: scriptFailure ? "sub_timeline_script_failure" : "sub_timeline_readiness_timeout",
|
|
58590
|
-
message: scriptFailure ? "A sub-composition timeline script failed to load" : `Sub-composition timelines did not become ready within ${timeoutMs}ms`,
|
|
58591
|
-
details: { timeoutMs }
|
|
58579
|
+
message: scriptFailure ? hasRuntimeErrors ? `A sub-composition script threw during execution \u2014 timeline registration never arrived (${session.scriptLoadFailures.join(", ")})` : `A sub-composition timeline script failed to load (${session.scriptLoadFailures.join(", ")})` : `Sub-composition timelines did not become ready within ${timeoutMs}ms`,
|
|
58580
|
+
details: { timeoutMs, sources: [...session.scriptLoadFailures] }
|
|
58592
58581
|
}
|
|
58593
58582
|
]);
|
|
58594
58583
|
}
|
|
@@ -58672,6 +58661,11 @@ async function initializeSession(session) {
|
|
|
58672
58661
|
const diagnostic = formatConsoleDiagnostic(type, text, locationUrl);
|
|
58673
58662
|
if (!diagnostic.suppressHostLog) console.log(diagnostic.text);
|
|
58674
58663
|
appendBrowserDiagnostic(session, diagnostic.text);
|
|
58664
|
+
if (type === "error" && text.startsWith("[HyperFrames] composition script error:")) {
|
|
58665
|
+
const detail = text.slice("[HyperFrames] composition script error:".length).trim();
|
|
58666
|
+
const compId = detail.split(" ")[0] || "unknown";
|
|
58667
|
+
recordScriptLoadFailure(session, `runtime-error:${compId}`);
|
|
58668
|
+
}
|
|
58675
58669
|
});
|
|
58676
58670
|
page.on("pageerror", (err) => {
|
|
58677
58671
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -60863,7 +60857,8 @@ async function extractMediaMetadata(filePath) {
|
|
|
60863
60857
|
hasAudio: false,
|
|
60864
60858
|
isVFR: false,
|
|
60865
60859
|
hasAlpha: false,
|
|
60866
|
-
colorSpace: stillImageMeta.colorSpace
|
|
60860
|
+
colorSpace: stillImageMeta.colorSpace,
|
|
60861
|
+
frames: 1
|
|
60867
60862
|
};
|
|
60868
60863
|
}
|
|
60869
60864
|
throw new Error("[FFmpeg] No video stream found");
|
|
@@ -60889,6 +60884,8 @@ async function extractMediaMetadata(filePath) {
|
|
|
60889
60884
|
const streamDuration = videoStream.duration ? parseFloat(videoStream.duration) : 0;
|
|
60890
60885
|
const parsedStreamStart = videoStream.start_time ? parseFloat(videoStream.start_time) : 0;
|
|
60891
60886
|
const streamStart = Number.isFinite(parsedStreamStart) ? parsedStreamStart : 0;
|
|
60887
|
+
const parsedNbFrames = videoStream.nb_frames ? parseInt(videoStream.nb_frames, 10) : NaN;
|
|
60888
|
+
const frames = Number.isFinite(parsedNbFrames) && parsedNbFrames > 0 ? parsedNbFrames : void 0;
|
|
60892
60889
|
return {
|
|
60893
60890
|
durationSeconds: containerDuration,
|
|
60894
60891
|
videoStreamDurationSeconds: streamDuration > 0 ? streamDuration : containerDuration,
|
|
@@ -60900,7 +60897,8 @@ async function extractMediaMetadata(filePath) {
|
|
|
60900
60897
|
hasAudio: output?.streams.some((s) => s.codec_type === "audio") ?? false,
|
|
60901
60898
|
isVFR,
|
|
60902
60899
|
hasAlpha,
|
|
60903
|
-
colorSpace
|
|
60900
|
+
colorSpace,
|
|
60901
|
+
frames
|
|
60904
60902
|
};
|
|
60905
60903
|
})();
|
|
60906
60904
|
videoMetadataCache.set(filePath, probePromise);
|
|
@@ -85230,11 +85228,23 @@ import {
|
|
|
85230
85228
|
rmSync as rmSync7
|
|
85231
85229
|
} from "fs";
|
|
85232
85230
|
import { basename as basename5, dirname as dirname10, extname as extname5, join as join21, resolve as resolve9 } from "path";
|
|
85231
|
+
|
|
85232
|
+
// ../producer/src/utils/ffprobe.ts
|
|
85233
|
+
init_src();
|
|
85234
|
+
|
|
85235
|
+
// ../producer/src/services/render/artifactTransaction.ts
|
|
85233
85236
|
var defaultFileSystem = {
|
|
85234
85237
|
existsSync: existsSync19,
|
|
85235
85238
|
renameSync: renameSync3,
|
|
85236
85239
|
rmSync: rmSync7
|
|
85237
85240
|
};
|
|
85241
|
+
async function defaultArtifactDurationProbe(path) {
|
|
85242
|
+
const meta = await extractMediaMetadata(path);
|
|
85243
|
+
return {
|
|
85244
|
+
durationSeconds: meta.durationSeconds,
|
|
85245
|
+
frames: meta.frames
|
|
85246
|
+
};
|
|
85247
|
+
}
|
|
85238
85248
|
function createSiblingTransactionDirectory(destination) {
|
|
85239
85249
|
const parent = dirname10(destination);
|
|
85240
85250
|
const extension = extname5(destination);
|
|
@@ -85265,14 +85275,44 @@ function collectDirectoryFiles(root) {
|
|
|
85265
85275
|
visit(root);
|
|
85266
85276
|
return files;
|
|
85267
85277
|
}
|
|
85278
|
+
function durationToleranceSeconds(expected) {
|
|
85279
|
+
if (expected.toleranceSeconds !== void 0) return expected.toleranceSeconds;
|
|
85280
|
+
const fps = expected.fps;
|
|
85281
|
+
return fps && fps > 0 ? 1 / fps : 0.02;
|
|
85282
|
+
}
|
|
85283
|
+
function assertUsableProbedDuration(probedSeconds, expectedSeconds, stagingPath) {
|
|
85284
|
+
if (!Number.isFinite(probedSeconds) || probedSeconds <= 0) {
|
|
85285
|
+
throw new Error(
|
|
85286
|
+
`Render artifact duration probe returned no usable duration for ${stagingPath} (got ${String(probedSeconds)}); expected ${expectedSeconds.toFixed(3)}s. Refusing to publish an artifact whose duration cannot be verified.`
|
|
85287
|
+
);
|
|
85288
|
+
}
|
|
85289
|
+
}
|
|
85290
|
+
function assertDurationWithinTolerance(expectedSeconds, probedSeconds, toleranceSeconds, stagingPath) {
|
|
85291
|
+
const deficit = expectedSeconds - probedSeconds;
|
|
85292
|
+
if (deficit <= toleranceSeconds) return;
|
|
85293
|
+
throw new Error(
|
|
85294
|
+
`Render artifact is truncated: expected ${expectedSeconds.toFixed(3)}s, probed ${probedSeconds.toFixed(3)}s (deficit ${deficit.toFixed(3)}s exceeds tolerance ${toleranceSeconds.toFixed(3)}s). Artifact: ${stagingPath}`
|
|
85295
|
+
);
|
|
85296
|
+
}
|
|
85297
|
+
function assertFrameCountWithinTolerance(expectedFrames, probedFrames, stagingPath) {
|
|
85298
|
+
if (probedFrames === void 0 || !Number.isFinite(probedFrames) || probedFrames <= 0) {
|
|
85299
|
+
return;
|
|
85300
|
+
}
|
|
85301
|
+
const shortfall = expectedFrames - probedFrames;
|
|
85302
|
+
if (shortfall <= 1) return;
|
|
85303
|
+
throw new Error(
|
|
85304
|
+
`Render artifact is truncated: expected ${expectedFrames} frames, probed ${probedFrames} frames (shortfall ${shortfall} frames). Artifact: ${stagingPath}`
|
|
85305
|
+
);
|
|
85306
|
+
}
|
|
85268
85307
|
var ArtifactTransaction = class {
|
|
85269
|
-
constructor(destinationPath, kind, fileSystem = defaultFileSystem) {
|
|
85308
|
+
constructor(destinationPath, kind, fileSystem = defaultFileSystem, durationProbe = defaultArtifactDurationProbe) {
|
|
85270
85309
|
this.kind = kind;
|
|
85271
85310
|
this.fileSystem = fileSystem;
|
|
85272
85311
|
this.destinationPath = resolve9(destinationPath);
|
|
85273
85312
|
this.transactionDirectory = createSiblingTransactionDirectory(this.destinationPath);
|
|
85274
85313
|
this.stagingPath = join21(this.transactionDirectory, basename5(this.destinationPath));
|
|
85275
85314
|
this.backupPath = join21(this.transactionDirectory, "backup");
|
|
85315
|
+
this.durationProbe = durationProbe;
|
|
85276
85316
|
}
|
|
85277
85317
|
kind;
|
|
85278
85318
|
fileSystem;
|
|
@@ -85281,9 +85321,11 @@ var ArtifactTransaction = class {
|
|
|
85281
85321
|
transactionDirectory;
|
|
85282
85322
|
backupPath;
|
|
85283
85323
|
state = "active";
|
|
85284
|
-
|
|
85324
|
+
durationProbe;
|
|
85325
|
+
async validate(expected) {
|
|
85285
85326
|
if (this.kind === "file") {
|
|
85286
85327
|
assertReadableNonEmptyFile(this.stagingPath);
|
|
85328
|
+
if (expected) await this.assertArtifactDuration(expected);
|
|
85287
85329
|
return;
|
|
85288
85330
|
}
|
|
85289
85331
|
let files;
|
|
@@ -85299,11 +85341,37 @@ var ArtifactTransaction = class {
|
|
|
85299
85341
|
}
|
|
85300
85342
|
for (const file of files) assertReadableNonEmptyFile(file);
|
|
85301
85343
|
}
|
|
85302
|
-
|
|
85344
|
+
async assertArtifactDuration(expected) {
|
|
85345
|
+
const expectedSeconds = expected.expectedDurationSeconds;
|
|
85346
|
+
if (!Number.isFinite(expectedSeconds) || expectedSeconds <= 0) return;
|
|
85347
|
+
const probed = await this.runDurationProbe();
|
|
85348
|
+
assertUsableProbedDuration(probed.durationSeconds, expectedSeconds, this.stagingPath);
|
|
85349
|
+
const toleranceSeconds = durationToleranceSeconds(expected);
|
|
85350
|
+
assertDurationWithinTolerance(
|
|
85351
|
+
expectedSeconds,
|
|
85352
|
+
probed.durationSeconds,
|
|
85353
|
+
toleranceSeconds,
|
|
85354
|
+
this.stagingPath
|
|
85355
|
+
);
|
|
85356
|
+
if (expected.expectedFrames !== void 0) {
|
|
85357
|
+
assertFrameCountWithinTolerance(expected.expectedFrames, probed.frames, this.stagingPath);
|
|
85358
|
+
}
|
|
85359
|
+
}
|
|
85360
|
+
async runDurationProbe() {
|
|
85361
|
+
try {
|
|
85362
|
+
return await this.durationProbe(this.stagingPath);
|
|
85363
|
+
} catch (error) {
|
|
85364
|
+
throw new Error(
|
|
85365
|
+
`Render artifact duration probe failed for ${this.stagingPath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
85366
|
+
{ cause: error }
|
|
85367
|
+
);
|
|
85368
|
+
}
|
|
85369
|
+
}
|
|
85370
|
+
async commit() {
|
|
85303
85371
|
if (this.state !== "active") {
|
|
85304
85372
|
throw new Error(`Cannot commit an artifact transaction in state ${this.state}`);
|
|
85305
85373
|
}
|
|
85306
|
-
this.validate();
|
|
85374
|
+
await this.validate();
|
|
85307
85375
|
const hadDestination = this.fileSystem.existsSync(this.destinationPath);
|
|
85308
85376
|
if (this.kind === "file" || !hadDestination) {
|
|
85309
85377
|
this.fileSystem.renameSync(this.stagingPath, this.destinationPath);
|
|
@@ -86510,9 +86578,6 @@ init_assetResolution();
|
|
|
86510
86578
|
import { createReadStream as createReadStream4, existsSync as existsSync25, mkdirSync as mkdirSync13, readFileSync as readFileSync10 } from "fs";
|
|
86511
86579
|
import { join as join27, dirname as dirname13, resolve as resolve12, basename as basename6 } from "path";
|
|
86512
86580
|
|
|
86513
|
-
// ../producer/src/utils/ffprobe.ts
|
|
86514
|
-
init_src();
|
|
86515
|
-
|
|
86516
86581
|
// ../producer/src/services/renderMediaCollector.ts
|
|
86517
86582
|
init_esm10();
|
|
86518
86583
|
init_dist2();
|
|
@@ -89639,7 +89704,7 @@ async function discoverMediaFromBrowser(page) {
|
|
|
89639
89704
|
const htmlEl = el;
|
|
89640
89705
|
const isImage = htmlEl.tagName.toLowerCase() === "img";
|
|
89641
89706
|
const tagName19 = isImage ? "image" : htmlEl.tagName.toLowerCase() === "video" ? "video" : "audio";
|
|
89642
|
-
const id = htmlEl.id || (isImage ? autoImageIds.get(htmlEl) : void 0);
|
|
89707
|
+
const id = htmlEl.getAttribute("data-hf-render-id") || htmlEl.id || (isImage ? autoImageIds.get(htmlEl) : void 0);
|
|
89643
89708
|
if (!id) return;
|
|
89644
89709
|
const src = htmlEl.currentSrc || htmlEl.src || htmlEl.getAttribute("src") || "";
|
|
89645
89710
|
const start = parseFloat(htmlEl.getAttribute("data-start") || "0");
|
|
@@ -89686,7 +89751,7 @@ async function discoverAudioVolumeAutomationFromTimeline(page, audioIds, composi
|
|
|
89686
89751
|
const sampleStep = 1 / Math.min(60, Math.max(1, sampleFps));
|
|
89687
89752
|
const rawWindows = await page.evaluate((ids) => {
|
|
89688
89753
|
return ids.flatMap((id) => {
|
|
89689
|
-
const el = document.getElementById(id) ?? document.getElementById(id.replace(/-audio$/, ""));
|
|
89754
|
+
const el = window.__hfMediaEl?.(id) ?? document.getElementById(id) ?? document.getElementById(id.replace(/-audio$/, ""));
|
|
89690
89755
|
if (!(el instanceof HTMLAudioElement) && !(el instanceof HTMLVideoElement)) return [];
|
|
89691
89756
|
return [
|
|
89692
89757
|
{
|
|
@@ -89745,7 +89810,7 @@ async function discoverAudioVolumeAutomationFromTimeline(page, audioIds, composi
|
|
|
89745
89810
|
}
|
|
89746
89811
|
};
|
|
89747
89812
|
for (const { id, start, end } of clips2) {
|
|
89748
|
-
const el = document.getElementById(id) ?? document.getElementById(id.replace(/-audio$/, ""));
|
|
89813
|
+
const el = window.__hfMediaEl?.(id) ?? document.getElementById(id) ?? document.getElementById(id.replace(/-audio$/, ""));
|
|
89749
89814
|
if (!(el instanceof HTMLAudioElement) && !(el instanceof HTMLVideoElement)) continue;
|
|
89750
89815
|
const sampleStart = Math.max(0, start);
|
|
89751
89816
|
const sampleEnd = Math.min(duration, end);
|
|
@@ -89821,7 +89886,7 @@ async function discoverVideoVisibilityFromTimeline(page, compositionDuration) {
|
|
|
89821
89886
|
const BINARY_PRECISION = 1 / 60;
|
|
89822
89887
|
const entries2 = [];
|
|
89823
89888
|
for (const videoEl of videos) {
|
|
89824
|
-
const id = videoEl.id;
|
|
89889
|
+
const id = videoEl.getAttribute?.("data-hf-render-id") || videoEl.id;
|
|
89825
89890
|
if (!id) continue;
|
|
89826
89891
|
entries2.push({
|
|
89827
89892
|
id,
|
|
@@ -90633,7 +90698,7 @@ function shouldCopyExtractedFrames(platform3) {
|
|
|
90633
90698
|
}
|
|
90634
90699
|
function resolveVideoExtractionPolicy(env = process.env) {
|
|
90635
90700
|
const rawMode = env.HF_VIDEO_EXTRACTION_FAILURE_MODE?.trim().toLowerCase();
|
|
90636
|
-
const failureMode = rawMode === "observe" || rawMode === "
|
|
90701
|
+
const failureMode = rawMode === "observe" || rawMode === "off" ? rawMode : "enforce";
|
|
90637
90702
|
const maxTransientRetries = failureMode !== "off" && env.HF_VIDEO_EXTRACTION_MAX_RETRIES?.trim() === "1" ? 1 : 0;
|
|
90638
90703
|
return { failureMode, maxTransientRetries };
|
|
90639
90704
|
}
|
|
@@ -94305,7 +94370,10 @@ function applyRenderWarningPolicy(job, captureWarnings, log = defaultLogger) {
|
|
|
94305
94370
|
const hasAudioProcessingFailure = job.warnings.some(
|
|
94306
94371
|
(warning) => warning.code === "audio_processing_failed"
|
|
94307
94372
|
);
|
|
94308
|
-
|
|
94373
|
+
const hasSubTimelineScriptFailure = job.warnings.some(
|
|
94374
|
+
(warning) => warning.code === "sub_timeline_script_failure"
|
|
94375
|
+
);
|
|
94376
|
+
if (strictness === "strict" || hasAudioProcessingFailure || hasSubTimelineScriptFailure) {
|
|
94309
94377
|
throw new RenderQualityError(job.warnings);
|
|
94310
94378
|
}
|
|
94311
94379
|
}
|
|
@@ -96097,7 +96165,13 @@ async function executeRenderPipeline(input) {
|
|
|
96097
96165
|
} else {
|
|
96098
96166
|
observability.checkpoint("assemble", `skipped for ${outputFormat}`);
|
|
96099
96167
|
}
|
|
96100
|
-
artifactTransaction.validate(
|
|
96168
|
+
await artifactTransaction.validate(
|
|
96169
|
+
!isPngSequence && !isGif && Number.isFinite(job.duration) && job.duration > 0 ? {
|
|
96170
|
+
expectedDurationSeconds: job.duration,
|
|
96171
|
+
fps: fpsToNumber(job.config.fps),
|
|
96172
|
+
expectedFrames: captureTotalFrames
|
|
96173
|
+
} : void 0
|
|
96174
|
+
);
|
|
96101
96175
|
const totalElapsed = Date.now() - pipelineStart;
|
|
96102
96176
|
const tmpPeakBytes = existsSync30(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
96103
96177
|
recordTransientRetryObservability();
|
|
@@ -96169,7 +96243,7 @@ async function executeRenderPipeline(input) {
|
|
|
96169
96243
|
copyFileSync6(stagedOutputPath, debugOutput);
|
|
96170
96244
|
}
|
|
96171
96245
|
}
|
|
96172
|
-
artifactTransaction.commit();
|
|
96246
|
+
await artifactTransaction.commit();
|
|
96173
96247
|
job.outputPath = outputPath;
|
|
96174
96248
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
96175
96249
|
await eventPublisher.flush();
|
|
@@ -97515,8 +97589,8 @@ async function runFontLocalize(io, localize) {
|
|
|
97515
97589
|
}
|
|
97516
97590
|
|
|
97517
97591
|
// src/version.ts
|
|
97518
|
-
var VERSION = true ? "0.8.
|
|
97519
|
-
var PRODUCER_VERSION = true ? "0.8.
|
|
97592
|
+
var VERSION = true ? "0.8.18" : "0.0.0-dev";
|
|
97593
|
+
var PRODUCER_VERSION = true ? "0.8.18" : "0.0.0-dev";
|
|
97520
97594
|
|
|
97521
97595
|
// src/fontLocalizeCli.ts
|
|
97522
97596
|
async function readStdin() {
|