@hyperframes/studio 0.8.86 → 0.8.87

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.
Files changed (83) hide show
  1. package/dist/assets/hyperframes-player-CtNVImMi.js +473 -0
  2. package/dist/assets/{index-Cz3E_ZSj.js → index-B_MF86RE.js} +1 -1
  3. package/dist/assets/{index-8Fgryj7q.js → index-DJ-Ol7YS.js} +1 -1
  4. package/dist/assets/{index-d5DKK15Q.js → index-DZKcDAtf.js} +203 -203
  5. package/dist/assets/{index-mzZCha_N.css → index-Dx79V1Se.css} +1 -1
  6. package/dist/{chunk-3IOCVWB6.js → chunk-PQFEGZWM.js} +3 -1
  7. package/dist/chunk-PQFEGZWM.js.map +1 -0
  8. package/dist/{domEditingLayers-ZOOMN7CQ.js → domEditingLayers-3BAP6NNO.js} +2 -2
  9. package/dist/index.d.ts +203 -160
  10. package/dist/index.html +2 -2
  11. package/dist/index.js +1958 -1611
  12. package/dist/index.js.map +1 -1
  13. package/dist/styles.css +1 -1
  14. package/package.json +8 -8
  15. package/src/components/editor/DomEditOverlay.tsx +1 -2
  16. package/src/components/editor/DomEditOverlayHover.test.tsx +5 -0
  17. package/src/components/editor/DomEditSelectionChrome.test.tsx +0 -3
  18. package/src/components/editor/DomEditSelectionChrome.tsx +3 -13
  19. package/src/components/editor/LayersPanel.test.ts +14 -0
  20. package/src/components/editor/LayersPanel.tsx +2 -2
  21. package/src/components/editor/TopologyLens.tsx +2 -2
  22. package/src/components/editor/commitPreflightHandles.test.tsx +466 -0
  23. package/src/components/editor/domEditOverlayGestures.ts +0 -1
  24. package/src/components/editor/domEditOverlayStartGesture.ts +10 -1
  25. package/src/components/editor/domEditing.test.ts +29 -0
  26. package/src/components/editor/domEditingDom.ts +1 -0
  27. package/src/components/editor/domEditingTypes.ts +1 -0
  28. package/src/components/editor/marqueeCommit.test.tsx +84 -0
  29. package/src/components/editor/marqueeCommit.ts +13 -1
  30. package/src/components/editor/useColorGradingController.test.ts +24 -0
  31. package/src/components/editor/useColorGradingController.ts +3 -2
  32. package/src/components/editor/useDomEditOverlayGestures.ts +20 -5
  33. package/src/components/nle/useCompositionStack.test.tsx +53 -0
  34. package/src/components/nle/useCompositionStack.ts +4 -8
  35. package/src/hooks/domStyleCommit.ts +129 -0
  36. package/src/hooks/gsapEditOutcome.ts +2 -2
  37. package/src/hooks/gsapElementMatch.ts +38 -0
  38. package/src/hooks/gsapResizeIntercept.ts +10 -31
  39. package/src/hooks/gsapResizePreflight.ts +56 -0
  40. package/src/hooks/gsapRuntimeBridge.ts +66 -26
  41. package/src/hooks/keyframeCacheAstLoad.ts +4 -1
  42. package/src/hooks/useCommitPreflightCapabilities.ts +147 -0
  43. package/src/hooks/useDomEditCommits.ts +17 -182
  44. package/src/hooks/useDomEditPersist.ts +225 -0
  45. package/src/hooks/useDomEditPreviewSync.test.ts +58 -0
  46. package/src/hooks/useDomEditPreviewSync.ts +2 -4
  47. package/src/hooks/useDomEditSession.test.tsx +51 -1
  48. package/src/hooks/useDomEditSession.ts +11 -2
  49. package/src/hooks/useDomEditTextCommits.ts +15 -99
  50. package/src/hooks/useDomStyleCommit.test.tsx +155 -0
  51. package/src/hooks/useDomStyleCommit.ts +74 -0
  52. package/src/hooks/useGsapAnimationFetchFallback.test.ts +12 -0
  53. package/src/hooks/useGsapAnimationFetchFallback.ts +8 -2
  54. package/src/hooks/useGsapAwareEditing.test.tsx +4 -0
  55. package/src/hooks/useGsapAwareEditing.ts +1 -1
  56. package/src/hooks/useGsapTweenCache.ts +2 -48
  57. package/src/index.ts +10 -1
  58. package/src/player/components/Timeline.audioEffects.test.tsx +80 -0
  59. package/src/player/components/Timeline.bandEscape.test.tsx +75 -0
  60. package/src/player/components/Timeline.playheadRemount.test.tsx +3 -27
  61. package/src/player/components/TimelineGroupHeader.tsx +21 -10
  62. package/src/player/components/TimelineGroupLaneLabels.tsx +7 -2
  63. package/src/player/components/TimelineGroupRow.test.tsx +24 -33
  64. package/src/player/components/TimelineGroupRow.tsx +4 -1
  65. package/src/player/components/TimelineLanes.tsx +5 -5
  66. package/src/player/components/TimelineTrackHeader.test.tsx +27 -0
  67. package/src/player/components/TimelineTrackHeader.tsx +6 -3
  68. package/src/player/components/TimelineTypes.ts +1 -0
  69. package/src/player/components/timelineLaneProps.ts +1 -0
  70. package/src/player/components/timelineMountTestEnv.ts +29 -0
  71. package/src/player/components/useTimelineLabelColumn.ts +18 -0
  72. package/src/player/components/useTimelineLaneRowIndexes.ts +6 -1
  73. package/src/player/components/useTimelineProviderState.tsx +6 -12
  74. package/src/player/components/useTimelineRangeSelection.ts +13 -12
  75. package/src/player/hooks/useShadowPreviewReload.ts +2 -0
  76. package/src/player/hooks/useTimelinePlayer.shadowReload.test.ts +191 -0
  77. package/src/player/hooks/useTimelinePlayer.ts +29 -7
  78. package/src/player/lib/runtimeProtocol.test.ts +1 -0
  79. package/src/player/sceneSwap.test.ts +95 -0
  80. package/src/player/sceneSwap.ts +53 -0
  81. package/dist/assets/hyperframes-player-Dx-2Gpsu.js +0 -473
  82. package/dist/chunk-3IOCVWB6.js.map +0 -1
  83. /package/dist/{domEditingLayers-ZOOMN7CQ.js.map → domEditingLayers-3BAP6NNO.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -652,6 +652,7 @@ interface DomEditCapabilities {
652
652
  canApplyManualSize: boolean;
653
653
  canApplyManualRotation: boolean;
654
654
  reasonIfDisabled?: string;
655
+ commitCheckPending?: boolean;
655
656
  }
656
657
  interface DomEditTextField {
657
658
  key: string;
@@ -690,6 +691,20 @@ interface DomEditSelection extends PatchTarget {
690
691
  capabilities: DomEditCapabilities;
691
692
  gsapAnimations?: GsapAnimation$1[];
692
693
  }
694
+ interface DomEditContextOptions {
695
+ activeCompositionPath: string | null;
696
+ isMasterView: boolean;
697
+ preferClipAncestor?: boolean;
698
+ /** The group wrapper the user has drilled into (null = top level). Selection
699
+ * resolution treats groups as a unit unless drilled into one. */
700
+ activeGroupElement?: HTMLElement | null;
701
+ }
702
+
703
+ declare function resolveDomEditSelection(startEl: HTMLElement | null, options: DomEditContextOptions & {
704
+ projectId?: string | null;
705
+ skipSourceProbe?: boolean;
706
+ exactTarget?: boolean;
707
+ }): Promise<DomEditSelection | null>;
693
708
 
694
709
  /**
695
710
  * Agent prompt builder for HyperFrames element edit requests.
@@ -794,7 +809,7 @@ interface DomEditPatchBatchesResult {
794
809
  changed: boolean;
795
810
  }
796
811
 
797
- interface RecordEditInput$4 {
812
+ interface RecordEditInput$5 {
798
813
  label: string;
799
814
  coalesceKey?: string;
800
815
  files: Record<string, {
@@ -818,7 +833,7 @@ interface UseTimelineEditingOptions {
818
833
  showToast: (message: string, tone?: "error" | "info") => void;
819
834
  writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
820
835
  observeProjectFileVersion?: (path: string, version: string | null) => void;
821
- recordEdit: (input: RecordEditInput$4) => Promise<void>;
836
+ recordEdit: (input: RecordEditInput$5) => Promise<void>;
822
837
  reloadPreview: () => void;
823
838
  previewIframeRef: RefObject<HTMLIFrameElement | null>;
824
839
  pendingTimelineEditPathRef: MutableRefObject<Set<string>>;
@@ -1137,6 +1152,7 @@ interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides, Ti
1137
1152
  onDuplicateClip?: () => Promise<boolean>;
1138
1153
  canPasteClip?: () => boolean;
1139
1154
  theme?: Partial<TimelineTheme>;
1155
+ showAudioEffects?: boolean;
1140
1156
  }
1141
1157
 
1142
1158
  interface TimelineEmptyStateProps {
@@ -1390,6 +1406,7 @@ interface TimelineLaneBaseProps {
1390
1406
  contentGutter: number;
1391
1407
  trackContentWidth: number;
1392
1408
  theme: TimelineTheme;
1409
+ showAudioEffects?: boolean;
1393
1410
  displayTrackOrder: number[];
1394
1411
  rowHeights: readonly number[];
1395
1412
  rowGeometry: TimelineRowGeometry;
@@ -2470,7 +2487,7 @@ declare function findElementBlock(html: string, elementId: string): {
2470
2487
  isSelfClosing: boolean;
2471
2488
  } | null;
2472
2489
 
2473
- interface RecordEditInput$3 {
2490
+ interface RecordEditInput$4 {
2474
2491
  label: string;
2475
2492
  coalesceKey?: string;
2476
2493
  coalesceMs?: number;
@@ -2516,7 +2533,7 @@ declare function usePersistentEditHistory({ projectId }: UsePersistentEditHistor
2516
2533
  createdAt: number;
2517
2534
  }[];
2518
2535
  };
2519
- recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput$3) => Promise<void>;
2536
+ recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput$4) => Promise<void>;
2520
2537
  undo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2521
2538
  redo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2522
2539
  };
@@ -2754,7 +2771,7 @@ interface AudioMeterStripProps {
2754
2771
  }
2755
2772
  declare const AudioMeterStrip: react.NamedExoticComponent<AudioMeterStripProps>;
2756
2773
 
2757
- interface RecordEditInput$2 {
2774
+ interface RecordEditInput$3 {
2758
2775
  label: string;
2759
2776
  coalesceKey?: string;
2760
2777
  files: Record<string, {
@@ -2768,7 +2785,7 @@ interface UseClipboardOptions {
2768
2785
  domEditSelectionRef: React.MutableRefObject<DomEditSelection | null>;
2769
2786
  showToast: (message: string, tone?: "error" | "info") => void;
2770
2787
  writeProjectFile: (path: string, content: string) => Promise<void>;
2771
- recordEdit: (input: RecordEditInput$2) => Promise<void>;
2788
+ recordEdit: (input: RecordEditInput$3) => Promise<void>;
2772
2789
  reloadPreview: () => void;
2773
2790
  handleTimelineElementsDelete: (elements: TimelineElement[]) => Promise<void>;
2774
2791
  handleDomEditElementDelete: (selection: DomEditSelection) => Promise<void>;
@@ -2791,131 +2808,24 @@ interface InlineTextEditCommit {
2791
2808
  previousHtml: string;
2792
2809
  }
2793
2810
 
2794
- declare const SNAP_THRESHOLD_PX = 6;
2795
- /** Whether a move of this size has travelled far enough for snapping to apply. */
2796
- declare function snapEngagedForTravel(dx: number, dy: number): boolean;
2797
- interface SnapEdge {
2798
- position: number;
2799
- source: "grid";
2800
- id: string;
2801
- }
2802
- interface SnapTarget {
2803
- left: number;
2804
- top: number;
2805
- right: number;
2806
- bottom: number;
2807
- centerX: number;
2808
- centerY: number;
2809
- id: string;
2810
- }
2811
- interface SnapGuide {
2812
- axis: "x" | "y";
2813
- position: number;
2814
- /** Extent of the guide line (min of involved elements). */
2815
- from: number;
2816
- /** Extent of the guide line (max of involved elements). */
2817
- to: number;
2818
- }
2819
- interface SpacingGuide {
2820
- axis: "x" | "y";
2821
- /** Position of the gap (start of gap). */
2822
- position: number;
2823
- /** Size of the gap in pixels. */
2824
- size: number;
2825
- /** Extent for rendering the indicator. */
2826
- from: number;
2827
- /** Extent for rendering the indicator. */
2828
- to: number;
2829
- }
2830
- interface SnapResult {
2831
- dx: number;
2832
- dy: number;
2833
- guides: SnapGuide[];
2834
- spacingGuides: SpacingGuide[];
2835
- }
2836
- interface Rect {
2837
- left: number;
2838
- top: number;
2839
- width: number;
2840
- height: number;
2841
- }
2842
2811
  /**
2843
- * Convert overlay rects to snap targets with precomputed edges & centers.
2844
- */
2845
- declare function extractSnapTargets(entries: Array<{
2846
- rect: Rect;
2847
- id: string;
2848
- }>): SnapTarget[];
2849
- /**
2850
- * Create a snap target from the composition/overlay boundary.
2851
- */
2852
- declare function buildCompositionSnapTarget(rect: Rect): SnapTarget;
2853
- /**
2854
- * Generate grid-line snap edges.
2855
- * `gridSpacing` is in composition pixels; `scale` converts to overlay pixels.
2856
- * X edges are vertical grid lines; Y edges are horizontal grid lines.
2812
+ * Why a DOM edit commit did not change the file.
2813
+ *
2814
+ * `runDomEditCommit` resolves on persist failure by design (see its contract
2815
+ * above), so a caller cannot learn whether the write landed by awaiting it — a
2816
+ * failed persist and a successful one are indistinguishable. Capture and apply
2817
+ * bugs still reject. The human path does not need to ask about handled persist
2818
+ * failures, because `onError` already put a toast on screen. A programmatic
2819
+ * caller has no screen, so it has to be told.
2857
2820
  */
2858
- declare function buildGridSnapEdges(compositionRect: Rect, gridSpacing: number, scale: number): {
2859
- x: SnapEdge[];
2860
- y: SnapEdge[];
2821
+ type DomEditCommitDeclineReason = "no-project" | "no-selection" | "geometry-property" | "styles-not-editable" | "not-text-editable" | "preview-stale" | "persist-failed";
2822
+ type DomEditCommitOutcome = {
2823
+ ok: true;
2824
+ persistence?: DomEditPersistOutcome;
2825
+ } | {
2826
+ ok: false;
2827
+ reason: DomEditCommitDeclineReason;
2861
2828
  };
2862
- declare function resolveSnapAdjustment(input: {
2863
- movingRect: Rect;
2864
- proposedDx: number;
2865
- proposedDy: number;
2866
- targets: SnapTarget[];
2867
- gridEdges?: {
2868
- x: SnapEdge[];
2869
- y: SnapEdge[];
2870
- };
2871
- threshold: number;
2872
- disabled: boolean;
2873
- /** Set when the gesture has not travelled far enough for snapping yet. */
2874
- disabledForTravel?: boolean;
2875
- }): SnapResult;
2876
- /**
2877
- * Full-length guide line spanning the composition: a vertical line (axis "x")
2878
- * runs the composition's height at the snapped x position; a horizontal line
2879
- * (axis "y") runs the composition's width. `composition` is the composition
2880
- * rect in overlay space — guide positions are already overlay-space, so the
2881
- * line must be offset by the composition's left/top (the canvas is usually
2882
- * letterboxed inside the overlay).
2883
- */
2884
- declare function resolveGuideLineRect(guide: SnapGuide, composition: Rect): Rect;
2885
- declare function resolveEquidistanceGuides(input: {
2886
- movingRect: Rect;
2887
- targets: SnapTarget[];
2888
- threshold: number;
2889
- }): SpacingGuide[];
2890
-
2891
- interface SnapContext {
2892
- targets: SnapTarget[];
2893
- compositionTarget: SnapTarget | null;
2894
- gridEdges: {
2895
- x: SnapEdge[];
2896
- y: SnapEdge[];
2897
- } | null;
2898
- snapEnabled: boolean;
2899
- }
2900
- declare function collectSnapContext(input: {
2901
- overlayEl: HTMLDivElement;
2902
- iframe: HTMLIFrameElement;
2903
- excludeElements: Set<HTMLElement>;
2904
- }): SnapContext;
2905
-
2906
- interface SnapGuidesState {
2907
- guides: SnapGuide[];
2908
- spacingGuides: SpacingGuide[];
2909
- }
2910
- interface SnapGuideOverlayProps {
2911
- snapGuidesRef: RefObject<SnapGuidesState | null>;
2912
- /** Composition rect in overlay space — guide lines span exactly this rect. */
2913
- compositionLeft: number;
2914
- compositionTop: number;
2915
- compositionWidth: number;
2916
- compositionHeight: number;
2917
- }
2918
- declare const SnapGuideOverlay: react.NamedExoticComponent<SnapGuideOverlayProps>;
2919
2829
 
2920
2830
  interface ApplyDomSelectionOptions {
2921
2831
  revealPanel?: boolean;
@@ -2950,33 +2860,6 @@ interface PreviewMouseDownOptions {
2950
2860
  hoverSelection?: DomEditSelection | null;
2951
2861
  }
2952
2862
 
2953
- interface DomEditGroupPathOffsetCommit {
2954
- selection: DomEditSelection;
2955
- next: {
2956
- x: number;
2957
- y: number;
2958
- };
2959
- }
2960
-
2961
- /**
2962
- * Why a DOM edit commit did not change the file.
2963
- *
2964
- * `runDomEditCommit` resolves on persist failure by design (see its contract
2965
- * above), so a caller cannot learn whether the write landed by awaiting it — a
2966
- * failed persist and a successful one are indistinguishable. Capture and apply
2967
- * bugs still reject. The human path does not need to ask about handled persist
2968
- * failures, because `onError` already put a toast on screen. A programmatic
2969
- * caller has no screen, so it has to be told.
2970
- */
2971
- type DomEditCommitDeclineReason = "no-project" | "no-selection" | "geometry-property" | "styles-not-editable" | "not-text-editable" | "preview-stale" | "persist-failed";
2972
- type DomEditCommitOutcome = {
2973
- ok: true;
2974
- persistence?: DomEditPersistOutcome;
2975
- } | {
2976
- ok: false;
2977
- reason: DomEditCommitDeclineReason;
2978
- };
2979
-
2980
2863
  /**
2981
2864
  * Which elements a delete acts on.
2982
2865
  *
@@ -2986,7 +2869,7 @@ type DomEditCommitOutcome = {
2986
2869
 
2987
2870
  /** One entry in the studio's edit history, as `useDomEditSession`'s caller
2988
2871
  * supplies it. */
2989
- interface RecordEditInput$1 {
2872
+ interface RecordEditInput$2 {
2990
2873
  label: string;
2991
2874
  coalesceKey?: string;
2992
2875
  files: Record<string, {
@@ -3005,7 +2888,7 @@ interface UseDomEditSessionParams extends DomEditTimelineParams {
3005
2888
  writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
3006
2889
  updateEditingFileContent: (path: string, content: string) => void;
3007
2890
  editHistory: {
3008
- recordEdit: (entry: RecordEditInput$1) => Promise<void>;
2891
+ recordEdit: (entry: RecordEditInput$2) => Promise<void>;
3009
2892
  };
3010
2893
  fileTree: string[];
3011
2894
  importedFontAssetsRef: React.MutableRefObject<ImportedFontAsset[]>;
@@ -3196,7 +3079,7 @@ interface HistoryPreviewRestore {
3196
3079
  paths?: string[];
3197
3080
  files?: Record<string, UndoRestoreFile>;
3198
3081
  }
3199
- interface RecordEditInput {
3082
+ interface RecordEditInput$1 {
3200
3083
  label: string;
3201
3084
  coalesceKey?: string;
3202
3085
  files: Record<string, {
@@ -3208,7 +3091,7 @@ interface UsePreviewPersistenceParams {
3208
3091
  showToast: (message: string, tone?: "error" | "info") => void;
3209
3092
  readOptionalProjectFile: (path: string) => Promise<string>;
3210
3093
  writeProjectFile: (path: string, content: string) => Promise<void>;
3211
- recordEdit: (entry: RecordEditInput) => Promise<void>;
3094
+ recordEdit: (entry: RecordEditInput$1) => Promise<void>;
3212
3095
  previewIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
3213
3096
  activeCompPathRef: React.MutableRefObject<string | null>;
3214
3097
  /** Called to reload the preview after undo/redo or external file changes. */
@@ -3251,6 +3134,140 @@ declare function PreviewReadOnlyProvider({ readOnly, reason, children, }: {
3251
3134
  children: ReactNode;
3252
3135
  }): react_jsx_runtime.JSX.Element;
3253
3136
 
3137
+ declare const SNAP_THRESHOLD_PX = 6;
3138
+ /** Whether a move of this size has travelled far enough for snapping to apply. */
3139
+ declare function snapEngagedForTravel(dx: number, dy: number): boolean;
3140
+ interface SnapEdge {
3141
+ position: number;
3142
+ source: "grid";
3143
+ id: string;
3144
+ }
3145
+ interface SnapTarget {
3146
+ left: number;
3147
+ top: number;
3148
+ right: number;
3149
+ bottom: number;
3150
+ centerX: number;
3151
+ centerY: number;
3152
+ id: string;
3153
+ }
3154
+ interface SnapGuide {
3155
+ axis: "x" | "y";
3156
+ position: number;
3157
+ /** Extent of the guide line (min of involved elements). */
3158
+ from: number;
3159
+ /** Extent of the guide line (max of involved elements). */
3160
+ to: number;
3161
+ }
3162
+ interface SpacingGuide {
3163
+ axis: "x" | "y";
3164
+ /** Position of the gap (start of gap). */
3165
+ position: number;
3166
+ /** Size of the gap in pixels. */
3167
+ size: number;
3168
+ /** Extent for rendering the indicator. */
3169
+ from: number;
3170
+ /** Extent for rendering the indicator. */
3171
+ to: number;
3172
+ }
3173
+ interface SnapResult {
3174
+ dx: number;
3175
+ dy: number;
3176
+ guides: SnapGuide[];
3177
+ spacingGuides: SpacingGuide[];
3178
+ }
3179
+ interface Rect {
3180
+ left: number;
3181
+ top: number;
3182
+ width: number;
3183
+ height: number;
3184
+ }
3185
+ /**
3186
+ * Convert overlay rects to snap targets with precomputed edges & centers.
3187
+ */
3188
+ declare function extractSnapTargets(entries: Array<{
3189
+ rect: Rect;
3190
+ id: string;
3191
+ }>): SnapTarget[];
3192
+ /**
3193
+ * Create a snap target from the composition/overlay boundary.
3194
+ */
3195
+ declare function buildCompositionSnapTarget(rect: Rect): SnapTarget;
3196
+ /**
3197
+ * Generate grid-line snap edges.
3198
+ * `gridSpacing` is in composition pixels; `scale` converts to overlay pixels.
3199
+ * X edges are vertical grid lines; Y edges are horizontal grid lines.
3200
+ */
3201
+ declare function buildGridSnapEdges(compositionRect: Rect, gridSpacing: number, scale: number): {
3202
+ x: SnapEdge[];
3203
+ y: SnapEdge[];
3204
+ };
3205
+ declare function resolveSnapAdjustment(input: {
3206
+ movingRect: Rect;
3207
+ proposedDx: number;
3208
+ proposedDy: number;
3209
+ targets: SnapTarget[];
3210
+ gridEdges?: {
3211
+ x: SnapEdge[];
3212
+ y: SnapEdge[];
3213
+ };
3214
+ threshold: number;
3215
+ disabled: boolean;
3216
+ /** Set when the gesture has not travelled far enough for snapping yet. */
3217
+ disabledForTravel?: boolean;
3218
+ }): SnapResult;
3219
+ /**
3220
+ * Full-length guide line spanning the composition: a vertical line (axis "x")
3221
+ * runs the composition's height at the snapped x position; a horizontal line
3222
+ * (axis "y") runs the composition's width. `composition` is the composition
3223
+ * rect in overlay space — guide positions are already overlay-space, so the
3224
+ * line must be offset by the composition's left/top (the canvas is usually
3225
+ * letterboxed inside the overlay).
3226
+ */
3227
+ declare function resolveGuideLineRect(guide: SnapGuide, composition: Rect): Rect;
3228
+ declare function resolveEquidistanceGuides(input: {
3229
+ movingRect: Rect;
3230
+ targets: SnapTarget[];
3231
+ threshold: number;
3232
+ }): SpacingGuide[];
3233
+
3234
+ interface SnapContext {
3235
+ targets: SnapTarget[];
3236
+ compositionTarget: SnapTarget | null;
3237
+ gridEdges: {
3238
+ x: SnapEdge[];
3239
+ y: SnapEdge[];
3240
+ } | null;
3241
+ snapEnabled: boolean;
3242
+ }
3243
+ declare function collectSnapContext(input: {
3244
+ overlayEl: HTMLDivElement;
3245
+ iframe: HTMLIFrameElement;
3246
+ excludeElements: Set<HTMLElement>;
3247
+ }): SnapContext;
3248
+
3249
+ interface SnapGuidesState {
3250
+ guides: SnapGuide[];
3251
+ spacingGuides: SpacingGuide[];
3252
+ }
3253
+ interface SnapGuideOverlayProps {
3254
+ snapGuidesRef: RefObject<SnapGuidesState | null>;
3255
+ /** Composition rect in overlay space — guide lines span exactly this rect. */
3256
+ compositionLeft: number;
3257
+ compositionTop: number;
3258
+ compositionWidth: number;
3259
+ compositionHeight: number;
3260
+ }
3261
+ declare const SnapGuideOverlay: react.NamedExoticComponent<SnapGuideOverlayProps>;
3262
+
3263
+ interface DomEditGroupPathOffsetCommit {
3264
+ selection: DomEditSelection;
3265
+ next: {
3266
+ x: number;
3267
+ y: number;
3268
+ };
3269
+ }
3270
+
3254
3271
  /**
3255
3272
  * Pure z-order helpers for the canvas right-click context menu.
3256
3273
  *
@@ -3375,6 +3392,32 @@ interface ConnectedDomEditOverlayProps extends HostInputProps {
3375
3392
  }
3376
3393
  declare function ConnectedDomEditOverlay({ activeCompositionPath, showHoverSelection, shouldShowSelectedDomBounds, isGestureRecording, canvasInput, onTextEditingChange, onSelectionBoxClick, }: ConnectedDomEditOverlayProps): react_jsx_runtime.JSX.Element;
3377
3394
 
3395
+ interface RecordEditInput {
3396
+ label: string;
3397
+ coalesceKey?: string;
3398
+ coalesceMs?: number;
3399
+ files: Record<string, {
3400
+ before: string;
3401
+ after: string;
3402
+ }>;
3403
+ }
3404
+
3405
+ interface UseDomStyleCommitOptions {
3406
+ projectId: string | null;
3407
+ /** The preview the host already runs: the style applies there live, and it reseeks after a save. */
3408
+ iframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
3409
+ /** The same function objects the host gives the timeline, so there is one writer and one undo list. */
3410
+ writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
3411
+ recordEdit: (entry: RecordEditInput) => Promise<void>;
3412
+ activeCompPath?: string | null;
3413
+ showToast?: (message: string, tone?: "error" | "info") => void;
3414
+ }
3415
+ /** Saves style edits on a selection through Studio's own style commit, for a host without the editor. */
3416
+ declare function useDomStyleCommit({ projectId, iframeRef, writeProjectFile, recordEdit, activeCompPath, showToast, }: UseDomStyleCommitOptions): {
3417
+ commitStyle: (selection: DomEditSelection, styles: Record<string, string>) => Promise<DomEditCommitOutcome>;
3418
+ waitForPendingSaves: () => Promise<DomEditSaveDrainResult>;
3419
+ };
3420
+
3378
3421
  interface MarqueeGesturesDeps<T = DomEditSelection> {
3379
3422
  iframeRef: React.RefObject<HTMLIFrameElement | null>;
3380
3423
  overlayRef: React.RefObject<HTMLDivElement | null>;
@@ -3417,4 +3460,4 @@ interface MarqueeOverlayProps {
3417
3460
  */
3418
3461
  declare function MarqueeOverlay({ candidateRects, marqueeRect }: MarqueeOverlayProps): react_jsx_runtime.JSX.Element;
3419
3462
 
3420
- export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, AudioMeterStrip, type AudioMeterStripProps, AudioWaveform, type AudioWaveformProps, type BlockedTimelineEditIntent, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ConnectedDomEditOverlay, type ConnectedDomEditOverlayProps, DEFAULT_SHORTCUT_SECTIONS, type DomEditCapabilities, DomEditProvider, type DomEditSelection, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, ImageThumbnail, type ImageThumbnailProps, type MarqueeGestures, type MarqueeGesturesDeps, MarqueeOverlay, type MarqueeOverlayProps, type Rect$1 as MarqueeRect, NLEPreview, type PatchOperation, type PersistedRenderSettings, type PickedElement, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, PreviewReadOnlyProvider, type PreviewSnapPreferences, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, SNAP_THRESHOLD_PX, type ShortcutHint, type ShortcutSection, type SnapContext, type SnapEdge, type SnapGuide, SnapGuideOverlay, type SnapGuideOverlayProps, type SnapGuidesState, type Rect as SnapRect, type SnapResult, type SnapTarget, SnapToolbar, SourceEditor, type SpacingGuide, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, type ThumbnailPriority, Timeline, TimelineClipMenu, type TimelineClipRenderContext, type TimelineEditCallbacks, type TimelineEditOutcome, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineHistoryButtons, type TimelineHistoryButtonsProps, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, TimelineToolbar, type TimelineToolbarProps, type TimelineZIndexReorderCommit, type UseClipboardOptions, type UseDomEditSessionParams, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UsePreviewPersistenceParams, type UseProjectFileWriterOptions, type UseRenderClipContentOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildCompositionSnapTarget, buildGridSnapEdges, buildPickerAgentContextPreview, buildPickerAgentPrompt, collectSnapContext, extractSnapTargets, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, resolveEquidistanceGuides, resolveGuideLineRect, resolveIframe, resolveSnapAdjustment, resolveSourceFile, snapEngagedForTravel, useClipboard, useCompositionStack, useDomEditSelectionContext, useDomEditSession, useEditHistoryActions, useElementPicker, useMarqueeGestures, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, usePreviewPersistence, useProjectFileWriter, useRenderClipContent, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };
3463
+ export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, AudioMeterStrip, type AudioMeterStripProps, AudioWaveform, type AudioWaveformProps, type BlockedTimelineEditIntent, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ConnectedDomEditOverlay, type ConnectedDomEditOverlayProps, DEFAULT_SHORTCUT_SECTIONS, type DomEditCapabilities, type DomEditCommitDeclineReason, type DomEditCommitOutcome, type DomEditGroupPathOffsetCommit, DomEditOverlay, type DomEditOverlayProps, DomEditProvider, type DomEditSelection, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, ImageThumbnail, type ImageThumbnailProps, type MarqueeGestures, type MarqueeGesturesDeps, MarqueeOverlay, type MarqueeOverlayProps, type Rect$1 as MarqueeRect, NLEPreview, type PatchOperation, type PersistedRenderSettings, type PickedElement, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, PreviewReadOnlyProvider, type PreviewSnapPreferences, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, SNAP_THRESHOLD_PX, type ShortcutHint, type ShortcutSection, type SnapContext, type SnapEdge, type SnapGuide, SnapGuideOverlay, type SnapGuideOverlayProps, type SnapGuidesState, type Rect as SnapRect, type SnapResult, type SnapTarget, SnapToolbar, SourceEditor, type SpacingGuide, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, type ThumbnailPriority, Timeline, TimelineClipMenu, type TimelineClipRenderContext, type TimelineEditCallbacks, type TimelineEditOutcome, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineHistoryButtons, type TimelineHistoryButtonsProps, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, TimelineToolbar, type TimelineToolbarProps, type TimelineZIndexReorderCommit, type UseClipboardOptions, type UseDomEditSessionParams, type UseDomStyleCommitOptions, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UsePreviewPersistenceParams, type UseProjectFileWriterOptions, type UseRenderClipContentOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildCompositionSnapTarget, buildGridSnapEdges, buildPickerAgentContextPreview, buildPickerAgentPrompt, collectSnapContext, extractSnapTargets, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, resolveDomEditSelection, resolveEquidistanceGuides, resolveGuideLineRect, resolveIframe, resolveSnapAdjustment, resolveSourceFile, snapEngagedForTravel, useClipboard, useCompositionStack, useDomEditSelectionContext, useDomEditSession, useDomStyleCommit, useEditHistoryActions, useElementPicker, useMarqueeGestures, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, usePreviewPersistence, useProjectFileWriter, useRenderClipContent, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <title>HyperFrames Studio</title>
8
- <script type="module" crossorigin src="/assets/index-d5DKK15Q.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-mzZCha_N.css">
8
+ <script type="module" crossorigin src="/assets/index-DZKcDAtf.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-Dx79V1Se.css">
10
10
  </head>
11
11
  <body>
12
12
  <div data-hf-id="hf-aph5" id="root"></div>