@hyperframes/producer 0.1.13 → 0.1.14

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.
@@ -90223,7 +90223,7 @@ var Context = class {
90223
90223
  * @param layout - The layout to set.
90224
90224
  * @returns The layout function.
90225
90225
  */
90226
- setLayout = (layout) => this.#layout = layout;
90226
+ setLayout = (layout2) => this.#layout = layout2;
90227
90227
  /**
90228
90228
  * Gets the current layout for the response.
90229
90229
  *
@@ -102176,6 +102176,19 @@ function lintHyperframeHtml(html, options = {}) {
102176
102176
  )
102177
102177
  });
102178
102178
  }
102179
+ const clipIds = /* @__PURE__ */ new Map();
102180
+ const clipClasses = /* @__PURE__ */ new Map();
102181
+ for (const tag of tags) {
102182
+ const classAttr = readAttr(tag.raw, "class") || "";
102183
+ const classes = classAttr.split(/\s+/).filter(Boolean);
102184
+ if (!classes.includes("clip")) continue;
102185
+ const id = readAttr(tag.raw, "id");
102186
+ const info = { tag: tag.name, id: id || "", classes: classAttr };
102187
+ if (id) clipIds.set(`#${id}`, info);
102188
+ for (const cls of classes) {
102189
+ if (cls !== "clip") clipClasses.set(`.${cls}`, info);
102190
+ }
102191
+ }
102179
102192
  const classUsage = countClassUsage(tags);
102180
102193
  for (const script of scripts) {
102181
102194
  const localTimelineCompId = readRegisteredTimelineCompositionId(script.content);
@@ -102218,24 +102231,39 @@ ${right2.raw}`)
102218
102231
  });
102219
102232
  }
102220
102233
  }
102234
+ for (const win of gsapWindows) {
102235
+ const sel = win.targetSelector;
102236
+ const clipInfo = clipIds.get(sel) || clipClasses.get(sel);
102237
+ if (!clipInfo) continue;
102238
+ const elDesc = `<${clipInfo.tag}${clipInfo.id ? ` id="${clipInfo.id}"` : ""} class="${clipInfo.classes}">`;
102239
+ pushFinding({
102240
+ code: "gsap_animates_clip_element",
102241
+ severity: "error",
102242
+ message: `GSAP animation targets a clip element. Selector "${sel}" resolves to element ${elDesc}. The framework manages clip visibility \u2014 animate an inner wrapper instead.`,
102243
+ selector: sel,
102244
+ elementId: clipInfo.id || void 0,
102245
+ fixHint: "Wrap content in a child <div> and target that with GSAP.",
102246
+ snippet: truncateSnippet(win.raw)
102247
+ });
102248
+ }
102221
102249
  if (!localTimelineCompId || localTimelineCompId === rootCompositionId) {
102222
102250
  continue;
102223
102251
  }
102224
- for (const window3 of gsapWindows) {
102225
- if (!isSuspiciousGlobalSelector(window3.targetSelector)) {
102252
+ for (const win of gsapWindows) {
102253
+ if (!isSuspiciousGlobalSelector(win.targetSelector)) {
102226
102254
  continue;
102227
102255
  }
102228
- const className = getSingleClassSelector(window3.targetSelector);
102256
+ const className = getSingleClassSelector(win.targetSelector);
102229
102257
  if (className && (classUsage.get(className) || 0) < 2) {
102230
102258
  continue;
102231
102259
  }
102232
102260
  pushFinding({
102233
102261
  code: "unscoped_gsap_selector",
102234
102262
  severity: "warning",
102235
- message: `Timeline "${localTimelineCompId}" uses unscoped selector "${window3.targetSelector}" that will target elements in ALL compositions when bundled, causing data loss (opacity, transforms, etc.).`,
102236
- selector: window3.targetSelector,
102237
- fixHint: `Scope the selector: \`[data-composition-id="${localTimelineCompId}"] ${window3.targetSelector}\` or use a unique id.`,
102238
- snippet: truncateSnippet(window3.raw)
102263
+ message: `Timeline "${localTimelineCompId}" uses unscoped selector "${win.targetSelector}" that will target elements in ALL compositions when bundled, causing data loss (opacity, transforms, etc.).`,
102264
+ selector: win.targetSelector,
102265
+ fixHint: `Scope the selector: \`[data-composition-id="${localTimelineCompId}"] ${win.targetSelector}\` or use a unique id.`,
102266
+ snippet: truncateSnippet(win.raw)
102239
102267
  });
102240
102268
  }
102241
102269
  }
@@ -102488,6 +102516,58 @@ ${right2.raw}`)
102488
102516
  }
102489
102517
  }
102490
102518
  }
102519
+ for (const script of scripts) {
102520
+ const content = script.content;
102521
+ const hasExitTween = /\.to\s*\([^,]+,\s*\{[^}]*opacity\s*:\s*0/.test(content);
102522
+ const hasHardKill = /\.set\s*\([^,]+,\s*\{[^}]*(?:visibility\s*:\s*["']hidden["']|opacity\s*:\s*0)/.test(content);
102523
+ const hasCaptionLoop = /forEach|\.forEach\s*\(/.test(content) && /createElement|caption|group|cg-/.test(content);
102524
+ if (hasCaptionLoop && hasExitTween && !hasHardKill) {
102525
+ pushFinding({
102526
+ code: "caption_exit_missing_hard_kill",
102527
+ severity: "warning",
102528
+ message: "Caption exit animations (tl.to with opacity: 0) detected without a hard tl.set kill. Exit tweens can fail when karaoke word-level tweens conflict, leaving captions stuck on screen.",
102529
+ fixHint: 'Add `tl.set(groupEl, { opacity: 0, visibility: "hidden" }, group.end)` after every exit tl.to animation as a deterministic kill.'
102530
+ });
102531
+ }
102532
+ }
102533
+ for (const style of styles) {
102534
+ const content = style.content;
102535
+ const captionBlocks = content.matchAll(
102536
+ /(\.caption[-_]?(?:group|container|text|line|word)|#caption[-_]?container)\s*\{([^}]+)\}/gi
102537
+ );
102538
+ for (const [, selector, body] of captionBlocks) {
102539
+ if (!body) continue;
102540
+ const hasNowrap = /white-space\s*:\s*nowrap/i.test(body);
102541
+ const hasMaxWidth = /max-width/i.test(body);
102542
+ if (hasNowrap && !hasMaxWidth) {
102543
+ pushFinding({
102544
+ code: "caption_text_overflow_risk",
102545
+ severity: "warning",
102546
+ selector: (selector ?? "").trim(),
102547
+ message: `Caption selector "${(selector ?? "").trim()}" has white-space: nowrap but no max-width. Long phrases will clip off-screen.`,
102548
+ fixHint: "Add max-width: 1600px (landscape) or max-width: 900px (portrait) and overflow: hidden."
102549
+ });
102550
+ }
102551
+ }
102552
+ }
102553
+ for (const style of styles) {
102554
+ const content = style.content;
102555
+ const captionBlocks = content.matchAll(
102556
+ /(\.caption[-_]?(?:group|container|text|line)|#caption[-_]?container)\s*\{([^}]+)\}/gi
102557
+ );
102558
+ for (const [, selector, body] of captionBlocks) {
102559
+ if (!body) continue;
102560
+ if (/position\s*:\s*relative/i.test(body)) {
102561
+ pushFinding({
102562
+ code: "caption_container_relative_position",
102563
+ severity: "warning",
102564
+ selector: (selector ?? "").trim(),
102565
+ message: `Caption selector "${(selector ?? "").trim()}" uses position: relative which causes overflow and breaks caption stacking.`,
102566
+ fixHint: "Use position: absolute for all caption elements."
102567
+ });
102568
+ }
102569
+ }
102570
+ }
102491
102571
  {
102492
102572
  const externalScriptRe = /<script\b[^>]*\bsrc=["'](https?:\/\/[^"']+)["'][^>]*>/gi;
102493
102573
  let match2;
@@ -102506,11 +102586,13 @@ ${right2.raw}`)
102506
102586
  }
102507
102587
  }
102508
102588
  const errorCount = findings.filter((finding) => finding.severity === "error").length;
102509
- const warningCount = findings.length - errorCount;
102589
+ const warningCount = findings.filter((finding) => finding.severity === "warning").length;
102590
+ const infoCount = findings.filter((finding) => finding.severity === "info").length;
102510
102591
  return {
102511
102592
  ok: errorCount === 0,
102512
102593
  errorCount,
102513
102594
  warningCount,
102595
+ infoCount,
102514
102596
  findings
102515
102597
  };
102516
102598
  }
@@ -102829,6 +102911,14 @@ function quantizeTimeToFrame(timeSeconds, fps) {
102829
102911
  return frameIndex / safeFps;
102830
102912
  }
102831
102913
 
102914
+ // ../../node_modules/.bun/@chenglou+pretext@0.0.3/node_modules/@chenglou/pretext/dist/analysis.js
102915
+ var arabicScriptRe = new RegExp("\\p{Script=Arabic}", "u");
102916
+ var combiningMarkRe = new RegExp("\\p{M}", "u");
102917
+ var decimalDigitRe = new RegExp("\\p{Nd}", "u");
102918
+
102919
+ // ../../node_modules/.bun/@chenglou+pretext@0.0.3/node_modules/@chenglou/pretext/dist/measurement.js
102920
+ var emojiPresentationRe = new RegExp("\\p{Emoji_Presentation}", "u");
102921
+
102832
102922
  // ../engine/src/services/screenshotService.ts
102833
102923
  var cdpSessionCache = /* @__PURE__ */ new WeakMap();
102834
102924
  async function getCdpSession(page) {