hyperframes 0.7.21 → 0.7.22

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.
@@ -4,6 +4,7 @@ import {
4
4
  buildDomEditStylePatchOperation,
5
5
  buildDomEditTextPatchOperation,
6
6
  collectDomEditLayerItems,
7
+ domEditSelectionToFacts,
7
8
  findElementForSelection,
8
9
  findElementForTimelineElement,
9
10
  getDomEditLayerKey,
@@ -17,7 +18,7 @@ import {
17
18
  resolveDomEditSelection,
18
19
  serializeDomEditTextFields,
19
20
  setCompositionSourceMap
20
- } from "./chunk-SBGXX7WY.js";
21
+ } from "./chunk-AN2EWWK3.js";
21
22
 
22
23
  // src/components/nle/NLELayout.tsx
23
24
  import {
@@ -5196,11 +5197,6 @@ var STUDIO_RAZOR_TOOL_ENABLED = resolveStudioBooleanEnvFlag(
5196
5197
  ["VITE_STUDIO_ENABLE_RAZOR_TOOL", "VITE_STUDIO_RAZOR_TOOL_ENABLED"],
5197
5198
  true
5198
5199
  );
5199
- var STUDIO_STORYBOARD_ENABLED = resolveStudioBooleanEnvFlag(
5200
- env,
5201
- ["VITE_STUDIO_ENABLE_STORYBOARD", "VITE_STUDIO_STORYBOARD_ENABLED"],
5202
- false
5203
- );
5204
5200
  var STUDIO_PREVIEW_SELECTION_ENABLED = STUDIO_INSPECTOR_PANELS_ENABLED;
5205
5201
  var STUDIO_SDK_CUTOVER_ENABLED = resolveStudioBooleanEnvFlag(
5206
5202
  env,
@@ -12819,14 +12815,11 @@ function createTransformCommitHandlers({
12819
12815
 
12820
12816
  // src/components/editor/PropertyPanel.tsx
12821
12817
  import { classifyPropertyGroup } from "@hyperframes/core/gsap-parser";
12818
+ import { resolveEditingSections } from "@hyperframes/core/editing";
12822
12819
 
12823
12820
  // src/components/editor/propertyPanelMediaSection.tsx
12824
12821
  import { useState as useState20 } from "react";
12825
12822
  import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
12826
- var MEDIA_TAGS = /* @__PURE__ */ new Set(["video", "audio"]);
12827
- function isMediaElement(element) {
12828
- return MEDIA_TAGS.has(element.tagName);
12829
- }
12830
12823
  function MediaSection({
12831
12824
  projectDir,
12832
12825
  element,
@@ -13500,9 +13493,6 @@ var DEFAULT_COLOR_GRADING = {
13500
13493
  colorSpace: HF_COLOR_GRADING_COLOR_SPACE
13501
13494
  };
13502
13495
  var COLOR_GRADING_DATA_KEY = HF_COLOR_GRADING_ATTR.replace(/^data-/, "");
13503
- function isColorGradingCapableElement(element) {
13504
- return element.tagName === "video" || element.tagName === "img";
13505
- }
13506
13496
  function readColorGradingFromElement(element) {
13507
13497
  const grading = normalizeHfColorGrading2(element.dataAttributes[COLOR_GRADING_DATA_KEY]) ?? DEFAULT_COLOR_GRADING;
13508
13498
  return { ...grading, intensity: 1 };
@@ -18711,6 +18701,7 @@ var PropertyPanel = memo22(function PropertyPanel2({
18711
18701
  const manualRotationEditingDisabled = !element.capabilities.canApplyManualRotation;
18712
18702
  const sourceLabel = element.id ? `#${element.id}` : element.selector;
18713
18703
  const showEditableSections = element.capabilities.canEditStyles;
18704
+ const sections = resolveEditingSections(domEditSelectionToFacts(element, gsapAnimations.length));
18714
18705
  const manualOffset = readStudioPathOffset(element.element);
18715
18706
  const manualSize = readStudioBoxSize(element.element);
18716
18707
  const resolvedWidth = manualSize.width > 0 ? manualSize.width : parsePxMetricValue(styles.width ?? "") ?? element.boundingBox.width;
@@ -18833,7 +18824,7 @@ var PropertyPanel = memo22(function PropertyPanel2({
18833
18824
  onRemoveTextField
18834
18825
  }
18835
18826
  ),
18836
- (element.dataAttributes.start != null || gsapAnimations.length > 0) && // Render whenever there's an authored clip range OR animations to infer
18827
+ sections.timing && // Render whenever there's an authored clip range OR animations to infer
18837
18828
  // one from — a pure-GSAP element with no data-start still gets a Timing
18838
18829
  // range (TimingSection derives it from its tweens).
18839
18830
  /* @__PURE__ */ jsx54(
@@ -18844,7 +18835,7 @@ var PropertyPanel = memo22(function PropertyPanel2({
18844
18835
  onSetAttribute
18845
18836
  }
18846
18837
  ),
18847
- isMediaElement(element) && /* @__PURE__ */ jsx54(
18838
+ sections.media && /* @__PURE__ */ jsx54(
18848
18839
  MediaSection,
18849
18840
  {
18850
18841
  projectDir,
@@ -18855,7 +18846,7 @@ var PropertyPanel = memo22(function PropertyPanel2({
18855
18846
  onSetHtmlAttribute
18856
18847
  }
18857
18848
  ),
18858
- STUDIO_COLOR_GRADING_ENABLED && isColorGradingCapableElement(element) && /* @__PURE__ */ jsx54(
18849
+ STUDIO_COLOR_GRADING_ENABLED && sections.colorGrading && /* @__PURE__ */ jsx54(
18859
18850
  ColorGradingSection,
18860
18851
  {
18861
18852
  element,
@@ -22337,6 +22328,9 @@ function normalizeText(v) {
22337
22328
  const t = v.trim();
22338
22329
  return t === "" ? null : t;
22339
22330
  }
22331
+ function countHfIdInSource(source, id) {
22332
+ return source.split(`data-hf-id="${id}"`).length - 1 + (source.split(`data-hf-id='${id}'`).length - 1);
22333
+ }
22340
22334
  function resolveSnapshot(session, id) {
22341
22335
  const els = session.getElements();
22342
22336
  const exact = els.find((el) => el.scopedId === id);
@@ -22379,8 +22373,9 @@ function checkOpValue(op, el, hfId) {
22379
22373
  if (actual === expected) return null;
22380
22374
  return { kind: "value_mismatch", hfId, property, expected, actual };
22381
22375
  }
22382
- function sdkResolverShadowCheck(session, hfId, ops) {
22376
+ function sdkResolverShadowCheck(session, hfId, ops, sourceContent) {
22383
22377
  if (!resolveSnapshot(session, hfId)) {
22378
+ if (sourceContent !== void 0 && !sourceContent.includes(hfId)) return [];
22384
22379
  return [{ kind: "element_not_found", hfId }];
22385
22380
  }
22386
22381
  const shadowable = ops.filter(isShadowableOp);
@@ -22416,14 +22411,24 @@ function redactMismatches(mismatches) {
22416
22411
  actual: redactValue(m.actual)
22417
22412
  }));
22418
22413
  }
22419
- function runResolverShadow(session, hfId, ops) {
22414
+ function runResolverShadow(session, hfId, ops, sourceContent) {
22420
22415
  if (!STUDIO_SDK_RESOLVER_SHADOW_ENABLED) return;
22421
22416
  if (!hfId) return;
22422
22417
  try {
22423
- const mismatches = sdkResolverShadowCheck(session, hfId, ops);
22418
+ const mismatches = sdkResolverShadowCheck(session, hfId, ops, sourceContent);
22424
22419
  if (mismatches.length === 0) return;
22420
+ const isElementNotFound = mismatches.some((m) => m.kind === "element_not_found");
22425
22421
  trackStudioEvent("sdk_resolver_shadow", {
22426
22422
  hfId,
22423
+ // sessionElementCount > 0 + element_not_found = runtime-only element;
22424
+ // sessionElementCount === 0 = session is empty/broken (actionable).
22425
+ sessionElementCount: session.getElements().length,
22426
+ // Count of data-hf-id="<id>" occurrences in source for an emitted
22427
+ // element_not_found (the runtime-node filter already dropped absent-from-
22428
+ // source ids, so an emitted one is in source ≥1×). >1 = duplicate ids →
22429
+ // resolver picked the wrong instance; =1 = single static node the SDK
22430
+ // parse dropped (foreign-content exclusion / sub-comp inlining gap).
22431
+ ...isElementNotFound && sourceContent !== void 0 ? { sourceHfIdCount: countHfIdInSource(sourceContent, hfId) } : {},
22427
22432
  mismatchCount: mismatches.length,
22428
22433
  mismatches: JSON.stringify(redactMismatches(mismatches))
22429
22434
  });
@@ -22438,6 +22443,7 @@ function recordResolverParity(session, hfId, opLabel) {
22438
22443
  trackStudioEvent("sdk_resolver_shadow", {
22439
22444
  hfId,
22440
22445
  opLabel,
22446
+ sessionElementCount: session.getElements().length,
22441
22447
  mismatchCount: 1,
22442
22448
  mismatches: JSON.stringify([
22443
22449
  { kind: "element_not_found", hfId }
@@ -22450,11 +22456,13 @@ function recordAnimationResolverParity(session, animationId, opLabel) {
22450
22456
  if (!STUDIO_SDK_RESOLVER_SHADOW_ENABLED) return;
22451
22457
  if (!session || !animationId) return;
22452
22458
  try {
22453
- const resolves = session.getElements().some((el) => el.animationIds.includes(animationId));
22459
+ const elements = session.getElements();
22460
+ const resolves = elements.some((el) => el.animationIds.includes(animationId));
22454
22461
  if (resolves) return;
22455
22462
  trackStudioEvent("sdk_resolver_shadow", {
22456
22463
  animationId,
22457
22464
  opLabel,
22465
+ sessionElementCount: elements.length,
22458
22466
  mismatchCount: 1,
22459
22467
  mismatches: JSON.stringify([
22460
22468
  { kind: "animation_not_found", animationId }
@@ -29916,7 +29924,7 @@ function useDomEditSession({
29916
29924
  buildDomSelectionFromTarget,
29917
29925
  forceReloadSdkSession,
29918
29926
  onTrySdkPersist: sdkSession ? (selection, operations, originalContent, targetPath, options) => {
29919
- runResolverShadow(sdkSession, selection.hfId, operations);
29927
+ runResolverShadow(sdkSession, selection.hfId, operations, originalContent);
29920
29928
  return sdkCutoverPersist(
29921
29929
  selection,
29922
29930
  operations,
@@ -32559,26 +32567,18 @@ function writeViewModeToUrl(mode) {
32559
32567
  }
32560
32568
  window.history.replaceState(window.history.state, "", url);
32561
32569
  }
32562
- function useViewModeState(enabled) {
32563
- const [viewMode, setMode] = useState58(
32564
- () => enabled ? readViewModeFromUrl() : "timeline"
32565
- );
32570
+ function useViewModeState() {
32571
+ const [viewMode, setMode] = useState58(() => readViewModeFromUrl());
32566
32572
  useEffect44(() => {
32567
- if (!enabled) return;
32568
32573
  const onPopState = () => setMode(readViewModeFromUrl());
32569
32574
  window.addEventListener("popstate", onPopState);
32570
32575
  return () => window.removeEventListener("popstate", onPopState);
32571
- }, [enabled]);
32572
- const setViewMode = useCallback77(
32573
- (mode) => {
32574
- if (!enabled) return;
32575
- setMode(mode);
32576
- writeViewModeToUrl(mode);
32577
- },
32578
- [enabled]
32579
- );
32580
- const effectiveMode = enabled ? viewMode : "timeline";
32581
- return useMemo27(() => ({ viewMode: effectiveMode, setViewMode }), [effectiveMode, setViewMode]);
32576
+ }, []);
32577
+ const setViewMode = useCallback77((mode) => {
32578
+ setMode(mode);
32579
+ writeViewModeToUrl(mode);
32580
+ }, []);
32581
+ return useMemo27(() => ({ viewMode, setViewMode }), [viewMode, setViewMode]);
32582
32582
  }
32583
32583
  var ViewModeContext = createContext5(null);
32584
32584
  function useViewMode() {
@@ -32828,7 +32828,7 @@ function StudioHeader({
32828
32828
  /* @__PURE__ */ jsx67("span", { className: "text-neutral-700 select-none", "aria-hidden": "true", children: "|" }),
32829
32829
  /* @__PURE__ */ jsx67("span", { className: "text-[11px] font-medium text-neutral-300", children: projectId })
32830
32830
  ] }),
32831
- STUDIO_STORYBOARD_ENABLED && /* @__PURE__ */ jsx67(ViewModeToggle, {}),
32831
+ /* @__PURE__ */ jsx67(ViewModeToggle, {}),
32832
32832
  /* @__PURE__ */ jsxs56("div", { className: "flex items-center gap-1.5", children: [
32833
32833
  /* @__PURE__ */ jsx67(
32834
32834
  "button",
@@ -36957,7 +36957,7 @@ function OffCanvasIndicators({
36957
36957
  const selectOffCanvas = async () => {
36958
36958
  const el = elements.current.get(r.key);
36959
36959
  if (!el) return;
36960
- const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-VZMLL4AP.js");
36960
+ const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-EK7R7R4G.js");
36961
36961
  const acp = activeCompositionPathRef.current ?? "index.html";
36962
36962
  const sel = await resolveDomEditSelection2(el, {
36963
36963
  activeCompositionPath: acp,
@@ -44757,7 +44757,7 @@ import { jsx as jsx113, jsxs as jsxs96 } from "react/jsx-runtime";
44757
44757
  function StudioApp() {
44758
44758
  const { projectId, resolving, waitingForServer } = useServerConnection();
44759
44759
  const initialUrlStateRef = useRef90(readStudioUrlStateFromWindow());
44760
- const viewModeValue = useViewModeState(STUDIO_STORYBOARD_ENABLED);
44760
+ const viewModeValue = useViewModeState();
44761
44761
  useEffect67(() => {
44762
44762
  if (resolving || waitingForServer) return;
44763
44763
  if (hasFiredSessionStart()) return;