hyperframes 0.8.42 → 0.8.44

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.
@@ -50279,7 +50279,7 @@ function resolveAliasDisplayName(alias) {
50279
50279
  if (!slug) return void 0;
50280
50280
  return CANONICAL_FONT_DISPLAY_NAMES[slug];
50281
50281
  }
50282
- var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50282
+ var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, HTML_BODY_CSS_WIDTH_FIRST_RE, HTML_BODY_CSS_HEIGHT_FIRST_RE, VIEWPORT_META_SIZE_RE, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50283
50283
  var init_dist = __esm({
50284
50284
  "../parsers/dist/index.js"() {
50285
50285
  "use strict";
@@ -50355,6 +50355,9 @@ var init_dist = __esm({
50355
50355
  COMPOSITION_ATTRIBUTES.legacyTrack
50356
50356
  ]);
50357
50357
  OK = { ok: true };
50358
+ HTML_BODY_CSS_WIDTH_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?width:\s*)(\d+)px([^}]*?height:\s*)(\d+)px/i;
50359
+ HTML_BODY_CSS_HEIGHT_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?height:\s*)(\d+)px([^}]*?width:\s*)(\d+)px/i;
50360
+ VIEWPORT_META_SIZE_RE = /(<meta[^>]*name=["']viewport["'][^>]*content=["']width=)(\d+)(,\s*height=)(\d+)/i;
50358
50361
  FONT_ALIAS_MAP = {
50359
50362
  // ── Canonical bundled fonts (self-referencing) ────────────────────────
50360
50363
  inter: "inter",
@@ -60402,6 +60405,31 @@ function getEncoderPreset(quality, format = "mp4", hdr) {
60402
60405
  }
60403
60406
  return { ...base2, pixelFormat: "yuv420p" };
60404
60407
  }
60408
+ function resolveLockedGopSize(options) {
60409
+ if (options.lockGopForChunkConcat !== true) return null;
60410
+ if (typeof options.gopSize !== "number" || !Number.isFinite(options.gopSize) || options.gopSize <= 0) {
60411
+ throw new Error(
60412
+ `[chunkEncoder] lockGopForChunkConcat=true requires a positive integer gopSize (received ${String(options.gopSize)})`
60413
+ );
60414
+ }
60415
+ return Math.floor(options.gopSize);
60416
+ }
60417
+ function appendLockedGopArgs(args, gopSize) {
60418
+ args.push(
60419
+ "-g",
60420
+ String(gopSize),
60421
+ "-keyint_min",
60422
+ String(gopSize),
60423
+ "-sc_threshold",
60424
+ "0",
60425
+ "-force_key_frames",
60426
+ `expr:eq(mod(n,${gopSize}),0)`
60427
+ );
60428
+ }
60429
+ function lockedGopCodecParams(codec, gopSize) {
60430
+ const shared = "scenecut=0:open-gop=0:repeat-headers=1";
60431
+ return codec === "h264" ? shared : `keyint=${gopSize}:min-keyint=${gopSize}:${shared}`;
60432
+ }
60405
60433
  function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
60406
60434
  const {
60407
60435
  fps,
@@ -60469,36 +60497,15 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
60469
60497
  args.push("-c:v", encoderName, "-preset", preset2);
60470
60498
  if (bitrate) args.push("-b:v", bitrate);
60471
60499
  else args.push("-crf", String(quality));
60472
- const lockGop = options.lockGopForChunkConcat === true;
60473
- let gop = 0;
60474
- if (lockGop) {
60475
- if (typeof options.gopSize !== "number" || !Number.isFinite(options.gopSize) || options.gopSize <= 0) {
60476
- throw new Error(
60477
- `[chunkEncoder] lockGopForChunkConcat=true requires a positive integer gopSize (received ${String(options.gopSize)})`
60478
- );
60479
- }
60480
- gop = Math.floor(options.gopSize);
60481
- args.push(
60482
- "-g",
60483
- String(gop),
60484
- "-keyint_min",
60485
- String(gop),
60486
- "-sc_threshold",
60487
- "0",
60488
- "-force_key_frames",
60489
- `expr:eq(mod(n,${gop}),0)`
60490
- );
60491
- }
60500
+ const gop = resolveLockedGopSize(options);
60501
+ const lockGop = gop !== null;
60502
+ if (gop !== null) appendLockedGopArgs(args, gop);
60492
60503
  if (codec === "h264" || codec === "h265" && lockGop) {
60493
60504
  args.push("-bf", "0");
60494
60505
  }
60495
60506
  const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
60496
60507
  const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
60497
- let gopParams = "";
60498
- if (lockGop) {
60499
- const shared = "scenecut=0:open-gop=0:repeat-headers=1";
60500
- gopParams = codec === "h264" ? shared : `keyint=${gop}:min-keyint=${gop}:${shared}`;
60501
- }
60508
+ const gopParams = gop !== null ? lockedGopCodecParams(codec, gop) : "";
60502
60509
  const joinParams = (...parts) => parts.filter((p) => p.length > 0).join(":");
60503
60510
  if (preset2 === "ultrafast") {
60504
60511
  args.push(xParamsFlag, joinParams("aq-mode=3", colorParams, gopParams));
@@ -60517,15 +60524,10 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
60517
60524
  args.push("-deadline", preset2 === "ultrafast" ? "realtime" : "good");
60518
60525
  args.push("-row-mt", "1");
60519
60526
  appendVp9CpuUsedArg(args, vp9CpuUsed);
60520
- const lockGopVp9 = options.lockGopForChunkConcat === true;
60521
- if (lockGopVp9) {
60522
- if (typeof options.gopSize !== "number" || !Number.isFinite(options.gopSize) || options.gopSize <= 0) {
60523
- throw new Error(
60524
- `[chunkEncoder] lockGopForChunkConcat=true requires a positive integer gopSize (received ${String(options.gopSize)})`
60525
- );
60526
- }
60527
- const gop = Math.floor(options.gopSize);
60528
- args.push("-g", String(gop), "-keyint_min", String(gop), "-auto-alt-ref", "0");
60527
+ const vp9Gop = resolveLockedGopSize(options);
60528
+ const lockGopVp9 = vp9Gop !== null;
60529
+ if (vp9Gop !== null) {
60530
+ args.push("-g", String(vp9Gop), "-keyint_min", String(vp9Gop), "-auto-alt-ref", "0");
60529
60531
  }
60530
60532
  if (pixelFormat === "yuva420p") {
60531
60533
  if (!lockGopVp9) {
@@ -61072,15 +61074,18 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
61072
61074
  args.push("-c:v", encoderName, "-preset", preset2);
61073
61075
  if (bitrate) args.push("-b:v", bitrate);
61074
61076
  else args.push("-crf", String(quality));
61075
- if (codec === "h264") {
61077
+ const lockedGop = resolveLockedGopSize(options);
61078
+ if (lockedGop !== null) appendLockedGopArgs(args, lockedGop);
61079
+ if (codec === "h264" || lockedGop !== null) {
61076
61080
  args.push("-bf", "0");
61077
61081
  }
61078
61082
  const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
61079
61083
  const colorParams = options.rawInputFormat && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
61084
+ const gopParams = lockedGop !== null ? `:${lockedGopCodecParams(codec, lockedGop)}` : "";
61080
61085
  if (preset2 === "ultrafast") {
61081
- args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
61086
+ args.push(xParamsFlag, `aq-mode=3:${colorParams}${gopParams}`);
61082
61087
  } else {
61083
- args.push(xParamsFlag, `aq-mode=3:aq-strength=0.8:deblock=1,1:${colorParams}`);
61088
+ args.push(xParamsFlag, `aq-mode=3:aq-strength=0.8:deblock=1,1:${colorParams}${gopParams}`);
61084
61089
  }
61085
61090
  if (codec === "h265") {
61086
61091
  args.push("-tag:v", "hvc1");
@@ -61311,6 +61316,7 @@ var init_streamingEncoder = __esm({
61311
61316
  init_dist2();
61312
61317
  init_vp9Options();
61313
61318
  init_renderProvenance();
61319
+ init_chunkEncoder();
61314
61320
  }
61315
61321
  });
61316
61322
 
@@ -69424,6 +69430,56 @@ function findVisibleMarkupCommentLeak(source) {
69424
69430
  }
69425
69431
  return null;
69426
69432
  }
69433
+ function readHtmlBodyCssSize(source) {
69434
+ const widthFirst = source.match(HTML_BODY_CSS_WIDTH_FIRST_RE);
69435
+ if (widthFirst) {
69436
+ const [, , width = "", , height = ""] = widthFirst;
69437
+ return { width, height };
69438
+ }
69439
+ const heightFirst = source.match(HTML_BODY_CSS_HEIGHT_FIRST_RE);
69440
+ if (heightFirst) {
69441
+ const [, , height = "", , width = ""] = heightFirst;
69442
+ return { width, height };
69443
+ }
69444
+ return null;
69445
+ }
69446
+ function readViewportMetaSize(source) {
69447
+ const match = source.match(VIEWPORT_META_SIZE_RE);
69448
+ if (!match) return null;
69449
+ const [, , width = "", , height = ""] = match;
69450
+ return { width, height };
69451
+ }
69452
+ function describeSizeMismatch(label, size, dataWidth, dataHeight) {
69453
+ if (!size || size.width === dataWidth && size.height === dataHeight) return null;
69454
+ return `${label} is ${size.width}x${size.height}`;
69455
+ }
69456
+ function describeRootDimensionsDrift(source, dataWidth, dataHeight) {
69457
+ const bodyCssMismatch = describeSizeMismatch(
69458
+ "html/body CSS",
69459
+ readHtmlBodyCssSize(source),
69460
+ dataWidth,
69461
+ dataHeight
69462
+ );
69463
+ const viewportMismatch = describeSizeMismatch(
69464
+ "the viewport meta",
69465
+ readViewportMetaSize(source),
69466
+ dataWidth,
69467
+ dataHeight
69468
+ );
69469
+ if (!bodyCssMismatch && !viewportMismatch) return null;
69470
+ const declared = `Root composition declares data-width="${dataWidth}" data-height="${dataHeight}"`;
69471
+ if (!bodyCssMismatch) {
69472
+ return {
69473
+ message: `${declared}, but ${viewportMismatch}. The viewport meta has no effect on capture \u2014 the renderer sizes the viewport from the root's own data-width/data-height \u2014 so this is stale metadata, not a clipping risk.`,
69474
+ fixHint: "update the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`"
69475
+ };
69476
+ }
69477
+ const mismatches = viewportMismatch ? `${bodyCssMismatch} and ${viewportMismatch}` : bodyCssMismatch;
69478
+ return {
69479
+ message: `${declared}, but ${mismatches}. The scaffolded body clips the composition at its old size.`,
69480
+ fixHint: "update html/body CSS and the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`"
69481
+ };
69482
+ }
69427
69483
  function tweensVolumeInSameCall(script, id) {
69428
69484
  const selector = new RegExp(`#${escapeRegExp3(id)}(?![\\w-])`, "g");
69429
69485
  for (let hit = selector.exec(script); hit; hit = selector.exec(script)) {
@@ -70920,6 +70976,7 @@ var init_dist3 = __esm({
70920
70976
  "use strict";
70921
70977
  init_esm6();
70922
70978
  import_postcss_selector_parser = __toESM(require_dist(), 1);
70979
+ init_dist();
70923
70980
  init_colorGradingContract();
70924
70981
  init_dist();
70925
70982
  init_esm10();
@@ -71031,6 +71088,39 @@ var init_dist3 = __esm({
71031
71088
  }
71032
71089
  return findings;
71033
71090
  },
71091
+ // root_dimensions_mismatch
71092
+ //
71093
+ // Render size and the runtime's forced #root size both read the root's own
71094
+ // data-width/data-height, so they stay correct. But editing only those two
71095
+ // attributes — rather than scaffolding with `hyperframes init --resolution`,
71096
+ // which rewrites the scaffold's other copies of the resolution too — leaves
71097
+ // the `html, body` CSS and the `<meta viewport>` at the old value, and a
71098
+ // stale body with `overflow: hidden` visually clips the correctly-sized
71099
+ // root. `hyperframes check`'s layout audits can't see it: they measure
71100
+ // against the root's own (already-correct) rect, not the body's.
71101
+ //
71102
+ // Sub-compositions are exempt: loadExternalCompositions (packages/core/src/
71103
+ // runtime/compositionLoader.ts) mounts only the matched <template>/<body>
71104
+ // subtree, so a sub-comp's own <html>/<head>/<meta viewport> never reach
71105
+ // the rendering document, even when it's a full standalone document.
71106
+ ({ rootTag, source, options }) => {
71107
+ if (!rootTag || options.isSubComposition) return [];
71108
+ const dataWidth = readAttr(rootTag.raw, "data-width");
71109
+ const dataHeight = readAttr(rootTag.raw, "data-height");
71110
+ if (!dataWidth || !dataHeight) return [];
71111
+ const drift = describeRootDimensionsDrift(source, dataWidth, dataHeight);
71112
+ if (!drift) return [];
71113
+ return [
71114
+ {
71115
+ code: "root_dimensions_mismatch",
71116
+ severity: "warning",
71117
+ message: drift.message,
71118
+ elementId: readAttr(rootTag.raw, "id") || void 0,
71119
+ fixHint: drift.fixHint,
71120
+ snippet: truncateSnippet(rootTag.raw)
71121
+ }
71122
+ ];
71123
+ },
71034
71124
  // unbalanced_style_tags
71035
71125
  ({ source }) => {
71036
71126
  let opens = 0;
@@ -87124,6 +87214,9 @@ function aggregateDrawElement(perfs, de) {
87124
87214
  preInversionWorkers: de.preInversionWorkers,
87125
87215
  compositionElementCount: de.compositionElementCount,
87126
87216
  compositionElementCountSource: de.compositionElementCountSource,
87217
+ compositionElementTags: de.compositionElementTags,
87218
+ arollVideoCount: de.arollVideoCount,
87219
+ heygenVideoCount: de.heygenVideoCount,
87127
87220
  shortBand: de.shortBand,
87128
87221
  parallelRouter: de.parallelRouter ?? "none",
87129
87222
  preRouterWorkers: de.preRouterWorkers,
@@ -96743,16 +96836,31 @@ function envInt(name, fallback) {
96743
96836
  const parsed = Number(raw);
96744
96837
  return Number.isInteger(parsed) ? parsed : fallback;
96745
96838
  }
96746
- function countElementTags(html) {
96839
+ var MAX_REPORTED_ELEMENT_TAGS = 50;
96840
+ function scanElementTags(html) {
96747
96841
  let markup = html;
96748
96842
  for (let previous = ""; markup !== previous; ) {
96749
96843
  previous = markup;
96750
96844
  markup = markup.replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1>/gi, "");
96751
96845
  }
96752
- const matches2 = markup.match(
96753
- /<\/[a-zA-Z]|<(?:img|br|hr|input|source|track|area|base|col|embed|link|meta|param|wbr)\b|<[a-zA-Z][-a-zA-Z0-9]*\b[^>]*\/>/gi
96846
+ let total = 0;
96847
+ const counts = /* @__PURE__ */ new Map();
96848
+ for (const m of markup.matchAll(
96849
+ /<\/([a-zA-Z][-a-zA-Z0-9]*)|<(img|br|hr|input|source|track|area|base|col|embed|link|meta|param|wbr)\b|<([a-zA-Z][-a-zA-Z0-9]*)\b[^>]*\/>/gi
96850
+ )) {
96851
+ total++;
96852
+ const tag = (m[1] ?? m[2] ?? m[3] ?? "").toLowerCase();
96853
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
96854
+ }
96855
+ const ranked = [...counts.entries()].sort((a, b) => b[1] - a[1]);
96856
+ const byTag = Object.fromEntries(
96857
+ ranked.slice(0, MAX_REPORTED_ELEMENT_TAGS)
96754
96858
  );
96755
- return matches2 === null ? 0 : matches2.length;
96859
+ const otherCount = ranked.slice(MAX_REPORTED_ELEMENT_TAGS).reduce((sum, [, count]) => sum + count, 0);
96860
+ if (otherCount > 0) byTag.other = (byTag.other ?? 0) + otherCount;
96861
+ const arollVideoCount = markup.match(/<video\b[^>]*\bdata-aroll=["']true["'][^>]*>/gi)?.length ?? 0;
96862
+ const heygenVideoCount = markup.match(/<video\b[^>]*\bdata-media-source=["']heygen["'][^>]*>/gi)?.length ?? 0;
96863
+ return { total, byTag, arollVideoCount, heygenVideoCount };
96756
96864
  }
96757
96865
  async function resolveCompositionElementCount(probeSession, html) {
96758
96866
  if (probeSession?.isInitialized) {
@@ -96768,7 +96876,14 @@ async function resolveCompositionElementCount(probeSession, html) {
96768
96876
  } catch {
96769
96877
  }
96770
96878
  }
96771
- return { count: countElementTags(html), source: "static" };
96879
+ const scan = scanElementTags(html);
96880
+ return {
96881
+ count: scan.total,
96882
+ source: "static",
96883
+ byTag: scan.byTag,
96884
+ arollVideoCount: scan.arollVideoCount,
96885
+ heygenVideoCount: scan.heygenVideoCount
96886
+ };
96772
96887
  }
96773
96888
  function mergeWorkerInitObservability(perfs) {
96774
96889
  let initDurationMs;
@@ -97426,7 +97541,13 @@ async function executeRenderPipeline(input) {
97426
97541
  const deSingleMinFrames = Number.isFinite(deSingleMinFramesNum) ? deSingleMinFramesNum : 900;
97427
97542
  const deShortBandMinFrames = envInt("HF_DE_SHORT_MIN_FRAMES", 250);
97428
97543
  const deShortBandMaxElements = envInt("HF_DE_SHORT_MAX_ELEMENTS", 2500);
97429
- const { count: compositionElementCount, source: compositionElementCountSource } = await resolveCompositionElementCount(probeSession, compiled.html);
97544
+ const {
97545
+ count: compositionElementCount,
97546
+ source: compositionElementCountSource,
97547
+ byTag: compositionElementTags,
97548
+ arollVideoCount,
97549
+ heygenVideoCount
97550
+ } = await resolveCompositionElementCount(probeSession, compiled.html);
97430
97551
  const deShortBandEnabled = deShortBandMaxElements > 0;
97431
97552
  const deShortBandOpen = deShortBandEnabled && deShortBandMinFrames > 0 && compositionElementCountSource === "live" && compositionElementCount <= deShortBandMaxElements;
97432
97553
  const deShortBandRoute = process.env.HF_DE_SHORT_BAND_ROUTE === "true";
@@ -97620,6 +97741,9 @@ async function executeRenderPipeline(input) {
97620
97741
  // perf shift can be split into "the new band did it" vs "unchanged".
97621
97742
  compositionElementCount,
97622
97743
  compositionElementCountSource,
97744
+ compositionElementTags,
97745
+ arollVideoCount,
97746
+ heygenVideoCount,
97623
97747
  deShortBand,
97624
97748
  // Same rationale as the counters above: carried on live capture
97625
97749
  // observability, not only the success-path perfSummary, so a crash /
@@ -98284,6 +98408,9 @@ async function executeRenderPipeline(input) {
98284
98408
  preInversionWorkers: deWorkerInversion ? preRoutingWorkerCount : void 0,
98285
98409
  compositionElementCount,
98286
98410
  compositionElementCountSource,
98411
+ compositionElementTags,
98412
+ arollVideoCount,
98413
+ heygenVideoCount,
98287
98414
  shortBand: deShortBand,
98288
98415
  parallelRouter: deParallelRouter,
98289
98416
  preRouterWorkers: deParallelRouter ? preRoutingWorkerCount : void 0,
@@ -99706,8 +99833,8 @@ async function runFontLocalize(io, localize) {
99706
99833
  }
99707
99834
 
99708
99835
  // src/version.ts
99709
- var VERSION = true ? "0.8.42" : "0.0.0-dev";
99710
- var PRODUCER_VERSION = true ? "0.8.42" : "0.0.0-dev";
99836
+ var VERSION = true ? "0.8.44" : "0.0.0-dev";
99837
+ var PRODUCER_VERSION = true ? "0.8.44" : "0.0.0-dev";
99711
99838
 
99712
99839
  // src/fontLocalizeCli.ts
99713
99840
  async function readStdin() {