@hyperframes/studio 0.8.59 → 0.8.61
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.
- package/dist/assets/{hyperframes-player-BBub3ZdI.js → hyperframes-player-nmVkPQza.js} +1 -1
- package/dist/assets/{index-CI7WON-E.js → index-2-HsQB2C.js} +1 -1
- package/dist/assets/{index-D1KNPijK.js → index-BK36b0XY.js} +162 -162
- package/dist/assets/{index-BxZ5Cw5w.js → index-COG0K-CQ.js} +1 -1
- package/dist/assets/{index-DZBHG9TW.css → index-DS0kLbuM.css} +1 -1
- package/dist/index.d.ts +5 -6
- package/dist/index.html +2 -2
- package/dist/index.js +4977 -4273
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +7 -7
- package/src/App.tsx +2 -0
- package/src/components/StudioHeader.tsx +2 -13
- package/src/components/TimelineToolbar.test.tsx +42 -0
- package/src/components/TimelineToolbar.tsx +5 -10
- package/src/components/editor/propertyPanelFill.tsx +3 -2
- package/src/components/icons/AudioMetersIcon.tsx +16 -0
- package/src/components/icons/InspectorIcon.tsx +18 -0
- package/src/components/icons/ReverseGradientIcon.tsx +23 -0
- package/src/components/icons/RippleEditIcon.tsx +19 -0
- package/src/components/nle/AudioMeterStrip.test.tsx +278 -7
- package/src/components/nle/AudioMeterStrip.tsx +264 -47
- package/src/components/ui/Menu.test.tsx +3 -4
- package/src/components/ui/Menu.tsx +18 -5
- package/src/components/ui/Select.tsx +7 -1
- package/src/components/ui/Tooltip.tsx +6 -1
- package/src/hooks/useExternalFileChangeCoordinator.test.tsx +56 -0
- package/src/hooks/useExternalFileChangeCoordinator.ts +13 -0
- package/src/hooks/useRenderClipContent.test.ts +33 -4
- package/src/hooks/useRenderClipContent.ts +7 -3
- package/src/hooks/useSdkSession.lifecycle.test.tsx +179 -0
- package/src/hooks/useSdkSession.ts +84 -14
- package/src/hooks/useStudioSdkSessions.ts +8 -1
- package/src/player/components/AudioWaveform.test.tsx +53 -1
- package/src/player/components/AudioWaveform.tsx +124 -65
- package/src/player/components/ImageThumbnail.tsx +3 -5
- package/src/player/components/LayerDisclosureRow.tsx +9 -4
- package/src/player/components/PlayheadIndicator.tsx +3 -3
- package/src/player/components/TimelineAutomationLane.test.tsx +1 -1
- package/src/player/components/TimelineAutomationLane.tsx +5 -5
- package/src/player/components/TimelineCanvas.tsx +18 -15
- package/src/player/components/TimelineClip.test.tsx +41 -4
- package/src/player/components/TimelineClip.tsx +11 -4
- package/src/player/components/TimelineClipDiamonds.test.tsx +3 -1
- package/src/player/components/TimelineClipDiamonds.tsx +2 -2
- package/src/player/components/TimelineClipFades.tsx +64 -31
- package/src/player/components/TimelineDiamondConnectors.tsx +2 -2
- package/src/player/components/TimelineEmptyState.tsx +1 -1
- package/src/player/components/TimelineFxButton.tsx +10 -8
- package/src/player/components/TimelineGroupHeader.tsx +18 -9
- package/src/player/components/TimelineGroupLaneLabels.tsx +12 -5
- package/src/player/components/TimelineGroupRow.tsx +1 -1
- package/src/player/components/TimelineLanes.test.tsx +14 -0
- package/src/player/components/TimelineLanes.tsx +15 -8
- package/src/player/components/TimelinePropertyLanes.test.tsx +1 -1
- package/src/player/components/TimelineRazorInteraction.tsx +1 -1
- package/src/player/components/TimelineRuler.tsx +3 -2
- package/src/player/components/TimelineShortcutHint.tsx +2 -2
- package/src/player/components/TimelineTrackHeader.test.tsx +1 -1
- package/src/player/components/TimelineTrackHeader.tsx +4 -6
- package/src/player/components/TimelineTrackPlainHeader.tsx +10 -3
- package/src/player/components/TimelineTransitionBadge.tsx +59 -0
- package/src/player/components/TimelineTransitionOverlays.tsx +30 -0
- package/src/player/components/VideoThumbnail.test.tsx +23 -12
- package/src/player/components/VideoThumbnail.tsx +86 -32
- package/src/player/components/audioClipLink.test.ts +34 -0
- package/src/player/components/audioClipLink.ts +33 -0
- package/src/player/components/audioWaveformPeaks.test.ts +32 -0
- package/src/player/components/audioWaveformPeaks.ts +46 -0
- package/src/player/components/thumbnailUtils.test.ts +17 -0
- package/src/player/components/thumbnailUtils.ts +7 -0
- package/src/player/components/timelineMotionStyles.test.ts +96 -30
- package/src/player/components/timelineTheme.test.ts +14 -0
- package/src/player/components/timelineTheme.ts +18 -11
- package/src/player/components/timelineTransitionSeams.test.ts +48 -0
- package/src/player/components/timelineTransitionSeams.ts +36 -0
- package/src/player/components/timelineZones.test.ts +18 -0
- package/src/player/components/timelineZones.ts +4 -1
- package/src/player/lib/playbackTypes.ts +2 -0
- package/src/player/lib/timelineDOM.test.ts +28 -0
- package/src/player/lib/timelineDOM.ts +24 -2
- package/src/player/lib/timelineIframeHelpers.ts +7 -0
- package/src/player/lib/timelineTransitionMetadata.ts +52 -0
- package/src/player/lib/timelineViewportBudgets.ts +2 -1
- package/src/player/store/timelineElement.ts +1 -0
- package/src/styles/hex-baseline.json +3 -22
- package/src/styles/studio.css +126 -46
- package/src/styles/theme.css +113 -1
- package/src/styles/theme.test.ts +9 -0
- package/src/utils/audioMeterVisibility.ts +2 -2
- package/src/utils/sdkCutover.test.ts +102 -1
- package/src/utils/sdkCutover.ts +16 -21
- package/src/utils/sdkEditTransaction.ts +50 -1
- package/src/utils/studioUiPreferences.ts +1 -1
|
@@ -4,6 +4,11 @@ import { hashContent, markSelfWrite } from "../hooks/sdkSelfWriteRegistry";
|
|
|
4
4
|
import { trackStudioEvent } from "./studioTelemetry";
|
|
5
5
|
import { serializeStudioFileMutation } from "./studioFileMutationCoordinator";
|
|
6
6
|
import type { StudioSdkOperationFamily } from "./sdkCutoverPolicy";
|
|
7
|
+
import {
|
|
8
|
+
StudioFileConflictError,
|
|
9
|
+
StudioSaveHttpError,
|
|
10
|
+
StudioSaveNetworkError,
|
|
11
|
+
} from "./studioSaveDiagnostics";
|
|
7
12
|
|
|
8
13
|
export type CutoverResult =
|
|
9
14
|
| { status: "declined"; reason: string }
|
|
@@ -91,10 +96,54 @@ export function declinedCutover(
|
|
|
91
96
|
return { status: "declined", reason };
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
function asCutoverError(error: unknown): Error {
|
|
95
100
|
return error instanceof Error ? error : new Error(String(error));
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
// Browser rejection strings for a fetch that never produced a response (offline,
|
|
104
|
+
// the dev server gone, a CSP/PNA block, an extension rewriting fetch). See
|
|
105
|
+
// `useSdkSession.ts`'s `readProjectFileOptional` catch for the same list.
|
|
106
|
+
const FETCH_REJECTION_MESSAGE = /Failed to fetch|Load failed|NetworkError when attempting to fetch/;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Classify a cutover failure for the gate dashboard. `writeProjectFile`'s own
|
|
110
|
+
* fetch wraps a rejection as `StudioSaveNetworkError`, but two raw fetches in
|
|
111
|
+
* this same transaction — `readProjectFile` (via `captureOnDiskBefore`) and
|
|
112
|
+
* `writeProjectFile`'s own read-before-write preflight — throw an unwrapped
|
|
113
|
+
* `TypeError` that reaches here undecorated. Without the message fallback,
|
|
114
|
+
* those file as `"sdk"` and trip the cutover-failure rollback gate on a
|
|
115
|
+
* network blip the SDK never had a chance to own.
|
|
116
|
+
*/
|
|
117
|
+
function cutoverErrorKind(error: Error): "network" | "conflict" | "http" | "sdk" {
|
|
118
|
+
if (error instanceof StudioSaveNetworkError) return "network";
|
|
119
|
+
if (error instanceof StudioFileConflictError) return "conflict";
|
|
120
|
+
if (error instanceof StudioSaveHttpError) return "http";
|
|
121
|
+
if (error.name === "TypeError" && FETCH_REJECTION_MESSAGE.test(error.message)) return "network";
|
|
122
|
+
return "sdk";
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Record a cutover that could not commit. Replaces ad hoc `trackStudioEvent("sdk_cutover_failed", ...)`
|
|
127
|
+
* calls so every gate event carries `family` and `error_kind` — without them the
|
|
128
|
+
* dashboard's rollback gate (any `sdk_cutover_failed` on a flipped version) cannot
|
|
129
|
+
* distinguish a real SDK defect from a rejected fetch it doesn't own.
|
|
130
|
+
*/
|
|
131
|
+
export function failedCutover(
|
|
132
|
+
error: unknown,
|
|
133
|
+
family: StudioSdkOperationFamily,
|
|
134
|
+
context: { hfId?: string | null; opCount?: number } = {},
|
|
135
|
+
): CutoverResult {
|
|
136
|
+
const err = asCutoverError(error);
|
|
137
|
+
trackStudioEvent("sdk_cutover_failed", {
|
|
138
|
+
...context,
|
|
139
|
+
family,
|
|
140
|
+
error_kind: cutoverErrorKind(err),
|
|
141
|
+
...(err instanceof StudioSaveHttpError ? { status: err.statusCode } : {}),
|
|
142
|
+
error: err.message,
|
|
143
|
+
});
|
|
144
|
+
return { status: "failed", error: err };
|
|
145
|
+
}
|
|
146
|
+
|
|
98
147
|
/** Only an explicit decline may enter the legacy mutation backend. */
|
|
99
148
|
export function cutoverCommittedOrThrow(result: CutoverResult): boolean {
|
|
100
149
|
if (result.status === "failed") throw result.error;
|
|
@@ -25,7 +25,7 @@ export interface StudioUiPreferences {
|
|
|
25
25
|
snapToGrid?: boolean;
|
|
26
26
|
/** Timeline magnet: snap clip drags/trims/drops to playhead, clip edges, and beats. */
|
|
27
27
|
timelineSnapEnabled?: boolean;
|
|
28
|
-
/** Audio level meters at the timeline's right edge;
|
|
28
|
+
/** Audio level meters at the timeline's right edge; hidden unless enabled here. */
|
|
29
29
|
audioMetersVisible?: boolean;
|
|
30
30
|
/** Keeps the main track gapless: deleting a clip closes the gap. Distinct
|
|
31
31
|
* from `timelineSnapEnabled` ("Magnet", drag/trim snapping). */
|