@hyperframes/producer 0.4.13 → 0.4.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.
@@ -102359,6 +102359,110 @@ var coreRules = [
102359
102359
  ];
102360
102360
 
102361
102361
  // ../core/src/lint/rules/media.ts
102362
+ function escapeRegExp(value) {
102363
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
102364
+ }
102365
+ function selectorTargetsManagedMedia(selector, mediaIds) {
102366
+ const normalized = selector.trim();
102367
+ if (!normalized) return false;
102368
+ if (/\b(video|audio)\b/i.test(normalized)) return true;
102369
+ for (const mediaId of mediaIds) {
102370
+ if (normalized.includes(`#${mediaId}`) || normalized.includes(`[id="${mediaId}"]`) || normalized.includes(`[id='${mediaId}']`)) {
102371
+ return true;
102372
+ }
102373
+ }
102374
+ return false;
102375
+ }
102376
+ function findImperativeMediaControlFindings(ctx) {
102377
+ const findings = [];
102378
+ const managedMediaIds = new Set(
102379
+ ctx.tags.filter((tag) => tag.name === "video" || tag.name === "audio").map((tag) => readAttr(tag.raw, "id")).filter((id) => Boolean(id))
102380
+ );
102381
+ if (managedMediaIds.size === 0 || ctx.scripts.length === 0) return findings;
102382
+ for (const script of ctx.scripts) {
102383
+ const mediaVars = /* @__PURE__ */ new Map();
102384
+ const assignmentPatterns = [
102385
+ /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)/g,
102386
+ /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:document|window\.document)\.querySelector\(\s*["']([^"']+)["']\s*\)/g
102387
+ ];
102388
+ for (const pattern of assignmentPatterns) {
102389
+ let match2;
102390
+ while ((match2 = pattern.exec(script.content)) !== null) {
102391
+ const variableName = match2[1];
102392
+ const target = match2[2];
102393
+ if (!variableName || !target) continue;
102394
+ if (managedMediaIds.has(target) || selectorTargetsManagedMedia(target, managedMediaIds)) {
102395
+ mediaVars.set(variableName, managedMediaIds.has(target) ? target : void 0);
102396
+ }
102397
+ }
102398
+ }
102399
+ const directIdPatterns = [
102400
+ {
102401
+ pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)\.play\s*\(/g,
102402
+ kind: "play()"
102403
+ },
102404
+ {
102405
+ pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)\.pause\s*\(/g,
102406
+ kind: "pause()"
102407
+ },
102408
+ {
102409
+ pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)\.currentTime\s*=/g,
102410
+ kind: "currentTime"
102411
+ },
102412
+ {
102413
+ pattern: /\b(?:document|window\.document)\.querySelector\(\s*["']([^"']+)["']\s*\)\.play\s*\(/g,
102414
+ kind: "play()"
102415
+ },
102416
+ {
102417
+ pattern: /\b(?:document|window\.document)\.querySelector\(\s*["']([^"']+)["']\s*\)\.pause\s*\(/g,
102418
+ kind: "pause()"
102419
+ },
102420
+ {
102421
+ pattern: /\b(?:document|window\.document)\.querySelector\(\s*["']([^"']+)["']\s*\)\.currentTime\s*=/g,
102422
+ kind: "currentTime"
102423
+ }
102424
+ ];
102425
+ for (const { pattern, kind } of directIdPatterns) {
102426
+ let match2;
102427
+ while ((match2 = pattern.exec(script.content)) !== null) {
102428
+ const target = match2[1];
102429
+ if (!target) continue;
102430
+ const elementId = managedMediaIds.has(target) ? target : selectorTargetsManagedMedia(target, managedMediaIds) ? void 0 : null;
102431
+ if (elementId === null) continue;
102432
+ findings.push({
102433
+ code: "imperative_media_control",
102434
+ severity: "error",
102435
+ message: `Inline <script> imperatively controls managed media via ${kind}. HyperFrames must own media play/pause/seek to keep preview, timeline, and renders deterministic.`,
102436
+ elementId: elementId || void 0,
102437
+ fixHint: "Remove imperative media play/pause/currentTime control. Express timing with data-start/data-duration and media offsets like data-media-start or data-playback-start instead.",
102438
+ snippet: truncateSnippet(match2[0])
102439
+ });
102440
+ }
102441
+ }
102442
+ for (const [variableName, elementId] of mediaVars) {
102443
+ const escapedVar = escapeRegExp(variableName);
102444
+ const variablePatterns = [
102445
+ { pattern: new RegExp(`\\b${escapedVar}\\.play\\s*\\(`, "g"), kind: "play()" },
102446
+ { pattern: new RegExp(`\\b${escapedVar}\\.pause\\s*\\(`, "g"), kind: "pause()" },
102447
+ { pattern: new RegExp(`\\b${escapedVar}\\.currentTime\\s*=`, "g"), kind: "currentTime" }
102448
+ ];
102449
+ for (const { pattern, kind } of variablePatterns) {
102450
+ let match2;
102451
+ while ((match2 = pattern.exec(script.content)) !== null) {
102452
+ findings.push({
102453
+ code: "imperative_media_control",
102454
+ severity: "error",
102455
+ message: `Inline <script> imperatively controls managed media via ${kind}. HyperFrames must own media play/pause/seek to keep preview, timeline, and renders deterministic.`,
102456
+ elementId,
102457
+ fixHint: "Remove imperative media play/pause/currentTime control. Express timing with data-start/data-duration and media offsets like data-media-start or data-playback-start instead.",
102458
+ snippet: truncateSnippet(match2[0])
102459
+ });
102460
+ }
102461
+ }
102462
+ }
102463
+ }
102464
+ return findings;
102465
+ }
102362
102466
  var mediaRules = [
102363
102467
  // duplicate_media_id + duplicate_media_discovery_risk
102364
102468
  ({ tags }) => {
@@ -102581,7 +102685,9 @@ var mediaRules = [
102581
102685
  }
102582
102686
  }
102583
102687
  return findings;
102584
- }
102688
+ },
102689
+ // imperative_media_control
102690
+ findImperativeMediaControlFindings
102585
102691
  ];
102586
102692
 
102587
102693
  // ../core/src/lint/rules/gsap.ts
@@ -110408,8 +110514,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110408
110514
  )
110409
110515
  });
110410
110516
  }
110411
- for (let layerIdx = 0; layerIdx < layers.length; layerIdx++) {
110412
- const layer = layers[layerIdx];
110517
+ for (const [layerIdx, layer] of layers.entries()) {
110413
110518
  if (layer.type === "hdr") {
110414
110519
  const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110415
110520
  const isHdrImage = nativeHdrImageIds.has(layer.element.id);