@hyperframes/studio 0.8.56 → 0.8.58

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 (91) hide show
  1. package/dist/assets/hyperframes-player-zGyOcwwh.js +464 -0
  2. package/dist/assets/{index-DFlILHJe.js → index-BcE2OSVA.js} +1 -1
  3. package/dist/assets/{index-ZmBtVrEm.css → index-DKJpHYYd.css} +1 -1
  4. package/dist/assets/{index-CxR7F2YQ.js → index-ZJaRCDYV.js} +1 -1
  5. package/dist/assets/{index-BlkJ_Axe.js → index-d8ferjRc.js} +194 -194
  6. package/dist/index.d.ts +124 -9
  7. package/dist/index.html +2 -2
  8. package/dist/index.js +15686 -14882
  9. package/dist/index.js.map +1 -1
  10. package/dist/styles.css +1 -1
  11. package/package.json +7 -7
  12. package/src/App.tsx +4 -0
  13. package/src/components/EditorShell.tsx +3 -1
  14. package/src/components/ProjectUnreachableBanner.test.tsx +113 -0
  15. package/src/components/ProjectUnreachableBanner.tsx +89 -0
  16. package/src/components/editor/DomEditOverlay.tsx +0 -15
  17. package/src/components/editor/GridOverlay.tsx +12 -23
  18. package/src/components/editor/MotionPathOverlay.test.tsx +65 -0
  19. package/src/components/editor/MotionPathOverlay.tsx +3 -1
  20. package/src/components/editor/PreviewGuides.test.tsx +6 -1
  21. package/src/components/editor/PreviewGuides.tsx +8 -10
  22. package/src/components/editor/PreviewOverlayProvider.test.tsx +90 -0
  23. package/src/components/editor/PreviewOverlayProvider.tsx +86 -0
  24. package/src/components/editor/SnapToolbar.test.tsx +25 -12
  25. package/src/components/editor/SnapToolbar.tsx +30 -59
  26. package/src/components/editor/propertyPanelFlatMediaSection.test.tsx +2 -2
  27. package/src/components/editor/propertyPanelFlatMediaSection.tsx +46 -12
  28. package/src/components/editor/usePreviewCompositionRect.test.tsx +19 -13
  29. package/src/components/editor/usePreviewCompositionRect.ts +12 -12
  30. package/src/components/editor/useVolumeAutomation.test.tsx +68 -0
  31. package/src/components/editor/useVolumeAutomation.ts +57 -16
  32. package/src/components/nle/NLEContext.tsx +48 -6
  33. package/src/components/nle/NLEPreview.test.ts +67 -1
  34. package/src/components/nle/NLEPreview.tsx +88 -44
  35. package/src/components/nle/PreviewOverlays.tsx +4 -16
  36. package/src/components/nle/PreviewPane.tsx +17 -2
  37. package/src/components/nle/previewReadOnly.test.tsx +1 -0
  38. package/src/components/nle/useCompositionStack.ts +1 -1
  39. package/src/hooks/useCompositionDimensions.test.tsx +37 -0
  40. package/src/hooks/useCompositionDimensions.ts +17 -1
  41. package/src/hooks/useDomEditAttributeCommits.test.ts +23 -0
  42. package/src/hooks/useDomEditAttributeCommits.ts +14 -3
  43. package/src/hooks/useFileTree.test.tsx +56 -0
  44. package/src/hooks/useFileTree.ts +8 -1
  45. package/src/hooks/useSdkSession.lifecycle.test.tsx +108 -0
  46. package/src/hooks/useSdkSession.ts +77 -14
  47. package/src/hooks/useServerConnection.hashProject.test.tsx +303 -0
  48. package/src/hooks/useServerConnection.ts +81 -8
  49. package/src/index.ts +21 -1
  50. package/src/player/components/LayerDisclosureRow.tsx +3 -3
  51. package/src/player/components/Player.test.ts +175 -13
  52. package/src/player/components/Player.tsx +58 -2
  53. package/src/player/components/ShortcutsPanel.test.tsx +4 -10
  54. package/src/player/components/Timeline.tsx +23 -572
  55. package/src/player/components/TimelineCanvas.tsx +9 -30
  56. package/src/player/components/TimelineGroupHeader.tsx +4 -6
  57. package/src/player/components/TimelineOverlays.test.ts +67 -32
  58. package/src/player/components/TimelineOverlays.tsx +46 -107
  59. package/src/player/components/TimelineProvider.tsx +191 -0
  60. package/src/player/components/TimelineTrackPlainHeader.test.tsx +10 -0
  61. package/src/player/components/TimelineTrackPlainHeader.tsx +4 -7
  62. package/src/player/components/testRootHarness.ts +18 -0
  63. package/src/player/components/timelineProviderStateBuilders.test.ts +109 -0
  64. package/src/player/components/timelineProviderStateBuilders.ts +83 -0
  65. package/src/player/components/useTimelineClipContextMenu.ts +1 -1
  66. package/src/player/components/useTimelineOverlaysState.ts +100 -0
  67. package/src/player/components/useTimelineProviderState.tsx +583 -0
  68. package/src/player/hooks/playbackAdapterResolution.test.ts +41 -0
  69. package/src/player/hooks/playbackAdapterResolution.ts +98 -0
  70. package/src/player/hooks/timelinePlayerTestHarness.ts +120 -0
  71. package/src/player/hooks/usePlayerHandle.test.tsx +152 -0
  72. package/src/player/hooks/usePlayerHandle.ts +94 -0
  73. package/src/player/hooks/usePreviewFirstFrameTelemetry.ts +51 -0
  74. package/src/player/hooks/useShadowPreviewReload.ts +183 -0
  75. package/src/player/hooks/useTimelinePlayer.seek.test.ts +8 -88
  76. package/src/player/hooks/useTimelinePlayer.shadowReload.test.ts +457 -0
  77. package/src/player/hooks/useTimelinePlayer.ts +65 -99
  78. package/src/player/hooks/useTimelineSyncCallbacks.ts +159 -88
  79. package/src/player/index.ts +7 -0
  80. package/src/telemetry/events.test.ts +18 -0
  81. package/src/telemetry/events.ts +10 -0
  82. package/src/telemetry/system.test.ts +49 -0
  83. package/src/telemetry/system.ts +6 -0
  84. package/src/telemetry/tabId.test.ts +43 -0
  85. package/src/telemetry/tabId.ts +44 -0
  86. package/src/utils/previewCompositionSize.ts +26 -0
  87. package/src/utils/reloadDebug.ts +2 -4
  88. package/src/utils/sourcePatcher.ts +1 -1
  89. package/src/utils/studioTelemetry.test.ts +14 -0
  90. package/src/utils/studioTelemetry.ts +4 -0
  91. package/dist/assets/hyperframes-player-k8LzMtXX.js +0 -464
package/dist/index.d.ts CHANGED
@@ -304,7 +304,15 @@ interface PlayerProps {
304
304
  projectId?: string;
305
305
  directUrl?: string;
306
306
  onLoad: () => void;
307
+ /** Fires once the loaded document is painted and every loader (shader, assets) has cleared. */
308
+ onReadyToShowChange?: (ready: boolean) => void;
309
+ onPreviewError?: (message: string) => void;
307
310
  onCompositionLoadingChange?: (loading: boolean) => void;
311
+ onPainted?: (details: {
312
+ iframe: HTMLIFrameElement;
313
+ startedAt: number;
314
+ loadId: number;
315
+ }) => void;
308
316
  portrait?: boolean;
309
317
  style?: React.CSSProperties;
310
318
  suppressLoadingOverlay?: boolean;
@@ -1370,6 +1378,23 @@ interface CompositionThumbnailProps {
1370
1378
  /** Server-rendered composition poster, deduplicated and budgeted by project/session. */
1371
1379
  declare const CompositionThumbnail: react.NamedExoticComponent<CompositionThumbnailProps>;
1372
1380
 
1381
+ /**
1382
+ * React callbacks for synchronising the player store from iframe runtime data.
1383
+ *
1384
+ * Covers four related concerns:
1385
+ * - processTimelineMessage — turn a clip-manifest postMessage into TimelineElements
1386
+ * - enrichMissingCompositions — fill gaps the manifest misses (element-ref starts)
1387
+ * - initializeAdapter — called after iframe load: seek, set duration, read elements
1388
+ * - onIframeLoad — orchestrates initializeAdapter with a message-based fallback
1389
+ */
1390
+
1391
+ type PreviewIframeRole = "live" | "shadow";
1392
+ interface PreviewIframeSlot {
1393
+ gen: number;
1394
+ role: PreviewIframeRole;
1395
+ url?: string;
1396
+ }
1397
+
1373
1398
  /**
1374
1399
  * Runtime iframe integration utilities.
1375
1400
  *
@@ -1404,7 +1429,13 @@ declare const CompositionThumbnail: react.NamedExoticComponent<CompositionThumbn
1404
1429
  */
1405
1430
  declare function resolveIframe(el: Element | null): HTMLIFrameElement | null;
1406
1431
 
1407
- declare function useTimelinePlayer(): {
1432
+ interface UseTimelinePlayerOptions {
1433
+ /** Runs right after a reloaded preview becomes the live iframe. */
1434
+ onShadowPromoted?: () => void;
1435
+ /** A reload was abandoned (cause in the message); the previous preview is still showing. */
1436
+ onPreviewReloadFailed?: (message: string) => void;
1437
+ }
1438
+ declare function useTimelinePlayer({ onShadowPromoted, onPreviewReloadFailed, }?: UseTimelinePlayerOptions): {
1408
1439
  iframeRef: react.RefObject<HTMLIFrameElement | null>;
1409
1440
  play: () => void;
1410
1441
  pause: () => void;
@@ -1412,12 +1443,47 @@ declare function useTimelinePlayer(): {
1412
1443
  seek: (time: number, options?: {
1413
1444
  keepPlaying?: boolean;
1414
1445
  }) => boolean;
1415
- onIframeLoad: () => void;
1446
+ onIframeLoad: (context?: number) => void;
1416
1447
  refreshPlayer: () => void;
1417
1448
  saveSeekPosition: () => void;
1418
1449
  resetPlayer: () => void;
1450
+ previewSlots: PreviewIframeSlot[];
1451
+ onShadowIframeLoad: (context?: number) => void;
1452
+ onShadowReadyChange: (gen: number, ready: boolean) => void;
1453
+ onShadowError: (gen: number, cause: string) => void;
1454
+ setShadowIframeNode: (node: HTMLIFrameElement | null) => void;
1455
+ resetPreviewSlots: () => void;
1419
1456
  };
1420
1457
 
1458
+ interface PlayerHandleElement {
1459
+ id: string;
1460
+ start: number;
1461
+ end: number;
1462
+ selector?: string;
1463
+ sourceFile?: string;
1464
+ compositionSrc?: string;
1465
+ }
1466
+ type PlayerHandleListener = () => void;
1467
+ type PlayerHandleTimeListener = (time: number) => void;
1468
+ interface PlayerHandle {
1469
+ ready: boolean;
1470
+ playing: boolean;
1471
+ seek: (seconds: number) => boolean;
1472
+ play: () => void;
1473
+ pause: () => void;
1474
+ togglePlay: () => void;
1475
+ readonly currentTime: number;
1476
+ duration: number;
1477
+ elements: PlayerHandleElement[];
1478
+ subscribe: (listener: PlayerHandleListener) => () => void;
1479
+ subscribeTime: (listener: PlayerHandleTimeListener) => () => void;
1480
+ }
1481
+ /**
1482
+ * Reads and controls the shell player. Call this under EditorShell/NLEProvider;
1483
+ * the provider owns the mounted preview iframe and the single player instance.
1484
+ */
1485
+ declare function usePlayerHandle(): PlayerHandle;
1486
+
1421
1487
  declare function formatTime(time: number): string;
1422
1488
 
1423
1489
  interface TimelineEditCallbackDeps {
@@ -1496,10 +1562,21 @@ interface EditorShellProps extends TimelineEditCallbackDeps {
1496
1562
  }
1497
1563
  declare function EditorShell({ panels, timelineToolbar, renderClipContent, handleTimelineElementDelete, handleTimelineAssetDrop, handleTimelineBlockDrop, handleTimelineCompositionDrop, handlePreviewBlockDrop, handleTimelineFileDrop, handleTimelineElementMove, handleTimelineElementsMove, handleTimelineElementResize, handleTimelineGroupResize, handleToggleTrackHidden, setAudioGroupAttribute, handleGroupClips, setElementFxAttribute, handleBlockedTimelineEdit, handleTimelineElementSplit, handleRazorSplit, handleRazorSplitAll, onCopyClip, onPasteClip, onDuplicateClip, canPasteClip, setCompIdToSrc, setCompositionLoading, shouldShowMotionPath, shouldShowSelectedDomBounds, isGestureRecording, recordingState, onToggleRecording, blockPreview, gestureOverlay, readOnlyPreview, readOnlyPreviewReason, }: EditorShellProps): react_jsx_runtime.JSX.Element;
1498
1564
 
1565
+ interface PreviewCompositionSize {
1566
+ width: number;
1567
+ height: number;
1568
+ }
1569
+
1499
1570
  interface NLEPreviewProps {
1500
1571
  projectId: string;
1501
1572
  iframeRef: RefObject<HTMLIFrameElement | null>;
1502
1573
  onIframeLoad: () => void;
1574
+ previewSlots: PreviewIframeSlot[];
1575
+ onShadowIframeLoad: (gen: number) => void;
1576
+ onShadowReadyChange: (gen: number, ready: boolean) => void;
1577
+ onShadowError: (gen: number, message: string) => void;
1578
+ setShadowIframeNode: (node: HTMLIFrameElement | null) => void;
1579
+ resetPreviewSlots: () => void;
1503
1580
  onCompositionLoadingChange?: (loading: boolean) => void;
1504
1581
  portrait?: boolean;
1505
1582
  directUrl?: string;
@@ -1508,10 +1585,6 @@ interface NLEPreviewProps {
1508
1585
  /** Reports the authored composition size measured from the loaded preview. */
1509
1586
  onCompositionSizeChange?: (size: PreviewCompositionSize | null) => void;
1510
1587
  }
1511
- interface PreviewCompositionSize {
1512
- width: number;
1513
- height: number;
1514
- }
1515
1588
  declare const NLEPreview: react.NamedExoticComponent<NLEPreviewProps>;
1516
1589
 
1517
1590
  interface CompositionLevel {
@@ -1539,9 +1612,51 @@ interface DomEditCompositionRect {
1539
1612
 
1540
1613
  /**
1541
1614
  * Where the composition sits inside `overlayRef`, in overlay pixels, plus the scale from
1542
- * composition units to pixels. Follows the live preview iframe across reloads.
1615
+ * composition units to pixels.
1543
1616
  */
1544
- declare function usePreviewCompositionRect(overlayRef: RefObject<HTMLDivElement | null>): DomEditCompositionRect;
1617
+ declare function usePreviewCompositionRect(overlayRef: RefObject<HTMLDivElement | null>, iframe: HTMLIFrameElement | null): DomEditCompositionRect;
1618
+
1619
+ interface PreviewSnapPreferences {
1620
+ snapEnabled: boolean;
1621
+ gridVisible: boolean;
1622
+ gridSpacing: number;
1623
+ snapToGrid: boolean;
1624
+ }
1625
+ interface PreviewOverlayContextValue {
1626
+ state: {
1627
+ snapPrefs: PreviewSnapPreferences;
1628
+ rulerVisible: boolean;
1629
+ safeMarginsVisible: boolean;
1630
+ iframeRef: RefObject<HTMLIFrameElement | null>;
1631
+ compositionRect: DomEditCompositionRect;
1632
+ };
1633
+ actions: {
1634
+ setSnapPrefs: (patch: Partial<PreviewSnapPreferences>) => void;
1635
+ toggleRulers: () => void;
1636
+ toggleSafeMargins: () => void;
1637
+ };
1638
+ }
1639
+ interface PreviewOverlayProviderProps {
1640
+ iframe?: HTMLIFrameElement | null;
1641
+ children: ReactNode;
1642
+ }
1643
+ declare function PreviewOverlayProvider({ iframe, children }: PreviewOverlayProviderProps): react_jsx_runtime.JSX.Element;
1644
+ declare function usePreviewOverlayContext(): PreviewOverlayContextValue;
1645
+
1646
+ /** Ruler and safe-margin boxes drawn over the preview pane, never inside the composition. */
1647
+ declare const PreviewGuides: react.NamedExoticComponent<object>;
1648
+
1649
+ declare const GridOverlay: react.NamedExoticComponent<object>;
1650
+
1651
+ declare const SnapToolbar: react.NamedExoticComponent<object>;
1652
+
1653
+ type GuideKey = "rulerVisible" | "safeMarginsVisible";
1654
+ interface PreviewGuidesState {
1655
+ rulerVisible: boolean;
1656
+ safeMarginsVisible: boolean;
1657
+ toggle: (key: GuideKey) => void;
1658
+ }
1659
+ declare const usePreviewGuidesStore: zustand.UseBoundStore<zustand.StoreApi<PreviewGuidesState>>;
1545
1660
 
1546
1661
  interface SourceEditorProps {
1547
1662
  content: string;
@@ -2187,4 +2302,4 @@ declare function TimelineEditProvider({ value, children, }: {
2187
2302
  children: ReactNode;
2188
2303
  }): react_jsx_runtime.JSX.Element;
2189
2304
 
2190
- export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, type BlockedTimelineEditIntent, Button, type ButtonSize, type ButtonVariant, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ContextMenu, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, HyperframesLoader, type HyperframesLoaderProps, HyperframesLogo, IconButton, Input, type InputProps, Menu, MenuItem, type MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NLEPreview, NumberField, type NumberFieldProps, type PatchOperation, type PersistedRenderSettings, type PickedElement, Player, PlayerControls, Popover, type PopupPreviewState, type DomEditCompositionRect as PreviewCompositionRect, type PreviewState, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, Select, type SelectOption, type SelectProps, Slider, type SliderProps, SourceEditor, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, Tab, TabPanel, Tabs, TabsList, Timeline, type TimelineEditCallbacks, type TimelineEditPermission, TimelineEditProvider, type TimelineElement, TimelinePane, type TimelinePaneProps, type TimelineTimeRange, Toggle, type ToggleProps, Tooltip, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UseProjectFileWriterOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, popupSurface, resolveIframe, resolveSourceFile, useEditHistoryActions, useElementPicker, usePersistentEditHistory, usePlayerStore, usePreviewCompositionRect, useProjectFileWriter, useRenderQueue, useTimelineEditing, useTimelinePlayer };
2305
+ export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, type BlockedTimelineEditIntent, Button, type ButtonSize, type ButtonVariant, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ContextMenu, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, HyperframesLoader, type HyperframesLoaderProps, HyperframesLogo, IconButton, Input, type InputProps, Menu, MenuItem, type MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NLEPreview, NumberField, type NumberFieldProps, type PatchOperation, type PersistedRenderSettings, type PickedElement, Player, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, Popover, type PopupPreviewState, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, type PreviewSnapPreferences, type PreviewState, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, Select, type SelectOption, type SelectProps, Slider, type SliderProps, SnapToolbar, SourceEditor, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, Tab, TabPanel, Tabs, TabsList, Timeline, type TimelineEditCallbacks, type TimelineEditPermission, TimelineEditProvider, type TimelineElement, TimelinePane, type TimelinePaneProps, type TimelineTimeRange, Toggle, type ToggleProps, Tooltip, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UseProjectFileWriterOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, popupSurface, resolveIframe, resolveSourceFile, useEditHistoryActions, useElementPicker, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, useProjectFileWriter, useRenderQueue, 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-BlkJ_Axe.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-ZmBtVrEm.css">
8
+ <script type="module" crossorigin src="/assets/index-d8ferjRc.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DKJpHYYd.css">
10
10
  </head>
11
11
  <body>
12
12
  <div data-hf-id="hf-aph5" id="root"></div>