@hyperframes/studio 0.7.107 → 0.7.109

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 (126) hide show
  1. package/dist/assets/{hyperframes-player-BLrfwq5o.js → hyperframes-player-BYgqAPib.js} +1 -1
  2. package/dist/assets/{index-BSBk5srs.js → index-Blxia-Lt.js} +1 -1
  3. package/dist/assets/{index-BA9yhzfR.js → index-CIRxodzK.js} +1 -1
  4. package/dist/assets/index-CfBGQdrX.js +428 -0
  5. package/dist/assets/index-DNkh9mbV.css +1 -0
  6. package/dist/index.d.ts +85 -2
  7. package/dist/index.html +2 -2
  8. package/dist/index.js +17696 -12512
  9. package/dist/index.js.map +1 -1
  10. package/package.json +7 -7
  11. package/src/components/StudioRightPanel.tsx +18 -1
  12. package/src/components/TimelineToolbar.test.tsx +46 -0
  13. package/src/components/TimelineToolbar.tsx +17 -0
  14. package/src/components/editor/PropertyPanel.test.tsx +5 -1
  15. package/src/components/editor/PropertyPanel.tsx +7 -23
  16. package/src/components/editor/PropertyPanelFlat.tsx +25 -0
  17. package/src/components/editor/audioFxSummary.test.ts +75 -0
  18. package/src/components/editor/audioFxSummary.ts +36 -0
  19. package/src/components/editor/audioFxTelemetry.test.ts +129 -0
  20. package/src/components/editor/audioFxTelemetry.ts +230 -0
  21. package/src/components/editor/propertyPanelAudioFxGroup.test.tsx +1830 -0
  22. package/src/components/editor/propertyPanelAudioFxGroup.tsx +299 -0
  23. package/src/components/editor/propertyPanelAudioFxGroupUtils.ts +21 -0
  24. package/src/components/editor/propertyPanelAutomation.test.ts +60 -0
  25. package/src/components/editor/propertyPanelAutomation.ts +97 -0
  26. package/src/components/editor/propertyPanelFlatMediaSection.tsx +37 -9
  27. package/src/components/editor/propertyPanelFlatProps.ts +1 -0
  28. package/src/components/editor/propertyPanelFxAddMenu.tsx +209 -0
  29. package/src/components/editor/propertyPanelFxBandRuler.tsx +72 -0
  30. package/src/components/editor/propertyPanelFxCarveModule.tsx +382 -0
  31. package/src/components/editor/propertyPanelFxControls.test.tsx +115 -0
  32. package/src/components/editor/propertyPanelFxControls.tsx +356 -0
  33. package/src/components/editor/propertyPanelFxEqModule.tsx +196 -0
  34. package/src/components/editor/propertyPanelFxFamily.ts +83 -0
  35. package/src/components/editor/propertyPanelFxNodeOpenBody.tsx +269 -0
  36. package/src/components/editor/propertyPanelFxNodeParams.tsx +112 -0
  37. package/src/components/editor/propertyPanelFxNodeRow.tsx +339 -0
  38. package/src/components/editor/propertyPanelFxPresetMenu.tsx +159 -0
  39. package/src/components/editor/propertyPanelFxPresetRun.tsx +215 -0
  40. package/src/components/editor/propertyPanelFxPresetStyle.test.ts +142 -0
  41. package/src/components/editor/propertyPanelFxPresetStyle.ts +216 -0
  42. package/src/components/editor/propertyPanelFxRackChain.tsx +202 -0
  43. package/src/components/editor/propertyPanelFxSection.test.tsx +1747 -0
  44. package/src/components/editor/propertyPanelFxSection.tsx +550 -0
  45. package/src/components/editor/propertyPanelFxSectionTypes.ts +91 -0
  46. package/src/components/editor/propertyPanelTypes.ts +5 -0
  47. package/src/components/editor/useFxAudition.ts +95 -0
  48. package/src/components/editor/useFxCarve.ts +0 -0
  49. package/src/components/editor/useFxChainObserved.ts +83 -0
  50. package/src/components/editor/useFxLevelling.ts +235 -0
  51. package/src/components/editor/useVolumeAutomation.test.tsx +122 -0
  52. package/src/components/editor/useVolumeAutomation.ts +54 -0
  53. package/src/contexts/DomEditContext.tsx +11 -0
  54. package/src/hooks/useAppHotkeys.test.ts +198 -0
  55. package/src/hooks/useAppHotkeys.ts +30 -3
  56. package/src/hooks/useAutomationSelectionKeyboard.test.tsx +429 -0
  57. package/src/hooks/useAutomationSelectionKeyboard.ts +371 -0
  58. package/src/hooks/useDomEditAttributeCommits.ts +90 -10
  59. package/src/hooks/useDomEditCommits.test.tsx +38 -0
  60. package/src/hooks/useDomEditCommits.ts +2 -0
  61. package/src/hooks/useDomEditSession.ts +2 -0
  62. package/src/hooks/useDomEditTextCommits.ts +2 -0
  63. package/src/hooks/useElementLifecycleOps.ts +3 -0
  64. package/src/hooks/useLivePlayheadTime.ts +49 -0
  65. package/src/hooks/usePreviewPersistence.ts +7 -0
  66. package/src/hooks/useTimelineEditing.ts +3 -0
  67. package/src/player/components/AutomationSelectionMenu.tsx +76 -0
  68. package/src/player/components/AutomationValueInput.tsx +51 -0
  69. package/src/player/components/LayerDisclosureRow.tsx +5 -4
  70. package/src/player/components/Timeline.test.ts +84 -0
  71. package/src/player/components/TimelineAutomationLane.test.tsx +1720 -0
  72. package/src/player/components/TimelineAutomationLane.tsx +674 -0
  73. package/src/player/components/TimelineAutomationLaneSlot.test.tsx +193 -0
  74. package/src/player/components/TimelineLanes.test.tsx +24 -5
  75. package/src/player/components/TimelineLanes.tsx +142 -154
  76. package/src/player/components/TimelineTrackHeader.test.tsx +212 -1
  77. package/src/player/components/TimelineTrackHeader.tsx +166 -6
  78. package/src/player/components/TimelineTrackRow.tsx +8 -1
  79. package/src/player/components/automationClipboard.test.ts +94 -0
  80. package/src/player/components/automationClipboard.ts +136 -0
  81. package/src/player/components/automationGestureKeys.test.ts +49 -0
  82. package/src/player/components/automationGestureKeys.ts +49 -0
  83. package/src/player/components/automationLaneData.test.ts +270 -0
  84. package/src/player/components/automationLaneData.ts +258 -0
  85. package/src/player/components/automationLaneDragMath.ts +194 -0
  86. package/src/player/components/automationLaneGeometry.test.ts +239 -0
  87. package/src/player/components/automationLaneGeometry.ts +287 -0
  88. package/src/player/components/automationLaneHeight.ts +15 -0
  89. package/src/player/components/automationLanePointer.ts +20 -0
  90. package/src/player/components/automationLaneSelection.test.ts +183 -0
  91. package/src/player/components/automationLaneSelection.ts +135 -0
  92. package/src/player/components/automationShapes.test.ts +82 -0
  93. package/src/player/components/automationShapes.ts +70 -0
  94. package/src/player/components/automationSimplify.test.ts +48 -0
  95. package/src/player/components/automationSimplify.ts +51 -0
  96. package/src/player/components/timelineClipGestureHandlers.ts +223 -0
  97. package/src/player/components/timelineLaneProps.ts +19 -0
  98. package/src/player/components/timelineLayout.ts +11 -5
  99. package/src/player/components/useAutomationEdgeStretch.test.ts +27 -0
  100. package/src/player/components/useAutomationEdgeStretch.ts +269 -0
  101. package/src/player/components/useAutomationLaneGestures.ts +537 -0
  102. package/src/player/components/useAutomationLanes.test.tsx +112 -0
  103. package/src/player/components/useAutomationLanes.ts +170 -0
  104. package/src/player/components/useAutomationRangeDrag.ts +114 -0
  105. package/src/player/components/useTimelineTrackLayout.test.ts +107 -1
  106. package/src/player/components/useTimelineTrackLayout.ts +83 -7
  107. package/src/player/hooks/useExpandedTimelineElements.ts +7 -0
  108. package/src/player/hooks/useTimelinePlayer.ts +13 -1
  109. package/src/player/lib/automationStoreSync.test.ts +83 -0
  110. package/src/player/lib/automationStoreSync.ts +56 -0
  111. package/src/player/lib/timelineDOM.test.ts +33 -0
  112. package/src/player/lib/timelineDOM.ts +12 -0
  113. package/src/player/store/automationSelectionSlice.test.ts +30 -0
  114. package/src/player/store/automationSelectionSlice.ts +54 -0
  115. package/src/player/store/playerStore.test.ts +15 -0
  116. package/src/player/store/playerStore.ts +54 -65
  117. package/src/player/store/timelineElement.ts +78 -0
  118. package/src/styles/studio.css +89 -0
  119. package/src/telemetry/agentRuntime.test.ts +45 -0
  120. package/src/telemetry/agentRuntime.ts +62 -0
  121. package/src/telemetry/system.ts +8 -0
  122. package/src/utils/studioFileHistory.test.ts +49 -0
  123. package/src/utils/studioFileHistory.ts +17 -1
  124. package/src/utils/studioTelemetry.ts +16 -10
  125. package/dist/assets/index-dF-CmLZu.js +0 -428
  126. package/dist/assets/index-zQ4JFwwB.css +0 -1
@@ -0,0 +1,202 @@
1
+ /**
2
+ * The rack's own signal path: the carve, the Tone EQ modules, and every
3
+ * hand-built effect or preset run in between — bracketed by the "In this
4
+ * track" / "Out to mix" labels that say the order is the point.
5
+ *
6
+ * Split out of `propertyPanelFxSection.tsx`, which owned this whole chain
7
+ * before the file grew past a size where the chain and the add/pick menus
8
+ * were still one thing to read.
9
+ */
10
+
11
+ import type { HfAudioFxChain, HfAudioFxNode } from "@hyperframes/core/audio-fx";
12
+ import { readAudioEqBands } from "@hyperframes/core/audio-fx-eq";
13
+ import { DEFAULT_CARVE, type HfCarveSettings } from "@hyperframes/core/audio-carve";
14
+ import { trackEqChanged, trackPresetAmount } from "./audioFxTelemetry.js";
15
+ import { FxCarveModule, type AudioTrackOption } from "./propertyPanelFxCarveModule.js";
16
+ import { FxEqModule } from "./propertyPanelFxEqModule.js";
17
+ import { FxPresetRun } from "./propertyPanelFxPresetRun.js";
18
+
19
+ export interface FxRackChainProps {
20
+ chain: HfAudioFxChain;
21
+ showCarve: boolean;
22
+ carveNodes: HfAudioFxNode[];
23
+ carve: HfCarveSettings | null;
24
+ sourceOptions: AudioTrackOption[];
25
+ automatedTargets?: ReadonlySet<string>;
26
+ liveAutomationValues?: ReadonlyMap<string, number>;
27
+ carveOpen: boolean;
28
+ disabled?: boolean;
29
+ analysing?: boolean;
30
+ onToggleCarveOpen(): void;
31
+ onCarveChange(carve: HfCarveSettings | null): void;
32
+ onCarvePreview(carve: HfCarveSettings): void;
33
+ eqIds: string[];
34
+ openEq: string | null;
35
+ onToggleEq(eqId: string): void;
36
+ onPreviewEqBand(eqId: string, band: string, gain: number): void;
37
+ onCommitEqBand(eqId: string, band: string, gain: number): void;
38
+ onRemoveEq(eqId: string): void;
39
+ handBuiltCount: number;
40
+ runs: { preset?: string; items: { node: HfAudioFxNode; i: number }[] }[];
41
+ positions: ReadonlyMap<number, number>;
42
+ openNode: number | null;
43
+ onToggleOpenNode(index: number): void;
44
+ onUpdateNode(index: number, patch: Partial<HfAudioFxNode>): void;
45
+ onMoveNode(index: number, delta: number): void;
46
+ onRemoveNode(index: number): void;
47
+ onPreviewNode(
48
+ index: number,
49
+ params: import("@hyperframes/core/audio-fx").HfAudioFxParamValues,
50
+ ): void;
51
+ trackKind?: string;
52
+ collapsedRuns: ReadonlySet<string>;
53
+ onToggleCollapse(runKey: string): void;
54
+ onSetRunAmount(
55
+ items: { node: HfAudioFxNode; i: number }[],
56
+ amount: number,
57
+ persist?: boolean,
58
+ ): void;
59
+ onRemoveRun(items: { node: HfAudioFxNode; i: number }[], presetId?: string): void;
60
+ onAutomateParam?(nodeId: string, paramKey: string): void;
61
+ onRemoveParamAutomation?(nodeId: string, paramKey: string): void;
62
+ presetAutomated: ReadonlySet<string>;
63
+ presetAutomateHandler(presetId: string | undefined, amount: number): (() => void) | undefined;
64
+ presetRemoveAutomationHandler(presetId: string | undefined): (() => void) | undefined;
65
+ }
66
+
67
+ export function FxRackChain({
68
+ chain,
69
+ showCarve,
70
+ carveNodes,
71
+ carve,
72
+ sourceOptions,
73
+ automatedTargets,
74
+ liveAutomationValues,
75
+ carveOpen,
76
+ disabled,
77
+ analysing,
78
+ onToggleCarveOpen,
79
+ onCarveChange,
80
+ onCarvePreview,
81
+ eqIds,
82
+ openEq,
83
+ onToggleEq,
84
+ onPreviewEqBand,
85
+ onCommitEqBand,
86
+ onRemoveEq,
87
+ handBuiltCount,
88
+ runs,
89
+ positions,
90
+ openNode,
91
+ onToggleOpenNode,
92
+ onUpdateNode,
93
+ onMoveNode,
94
+ onRemoveNode,
95
+ onPreviewNode,
96
+ trackKind,
97
+ collapsedRuns,
98
+ onToggleCollapse,
99
+ onSetRunAmount,
100
+ onRemoveRun,
101
+ onAutomateParam,
102
+ onRemoveParamAutomation,
103
+ presetAutomated,
104
+ presetAutomateHandler,
105
+ presetRemoveAutomationHandler,
106
+ }: FxRackChainProps) {
107
+ return (
108
+ <div className="hf-fx-chain space-y-1">
109
+ {/* The rack IS the signal path, and saying so costs two lines. Without
110
+ them the order reads as a list, which is the one reading that makes
111
+ "move up" look cosmetic — it is the most consequential control here. */}
112
+ <p className="hf-fx-term flex items-baseline gap-1.5 px-1.5 font-mono text-[9px] uppercase tracking-wide text-panel-text-2">
113
+ <span className="hf-fx-term-cap text-panel-text-1">In</span>
114
+ <span>this track</span>
115
+ </p>
116
+ {/* Carve leads the rack, which is also where its effects sit in the signal
117
+ path — corrective work before anything the author added. Present
118
+ whenever there is a voice for it to listen to, rather than appearing
119
+ only once it has already produced something: a control that materialises
120
+ after the fact cannot be the thing you reach for to start. */}
121
+ {showCarve ? (
122
+ <FxCarveModule
123
+ nodes={carveNodes}
124
+ carve={carve ?? { ...DEFAULT_CARVE }}
125
+ sourceOptions={sourceOptions}
126
+ automatedTargets={automatedTargets}
127
+ liveAutomationValues={liveAutomationValues}
128
+ open={carveOpen}
129
+ disabled={disabled}
130
+ analysing={analysing}
131
+ onToggleOpen={onToggleCarveOpen}
132
+ onCarveChange={onCarveChange}
133
+ onCarvePreview={onCarvePreview}
134
+ />
135
+ ) : null}
136
+ {eqIds.map((eqId) => (
137
+ <FxEqModule
138
+ key={eqId}
139
+ eqId={eqId}
140
+ bands={readAudioEqBands(chain, eqId)}
141
+ open={openEq === eqId}
142
+ disabled={disabled}
143
+ onToggleOpen={() => onToggleEq(eqId)}
144
+ onPreview={(band, gain) => onPreviewEqBand(eqId, band, gain)}
145
+ onCommit={(band, gain) => {
146
+ trackEqChanged(band, gain);
147
+ onCommitEqBand(eqId, band, gain);
148
+ }}
149
+ onRemove={() => onRemoveEq(eqId)}
150
+ />
151
+ ))}
152
+ {handBuiltCount === 0 && eqIds.length === 0 ? (
153
+ <p className="hf-fx-empty py-1 text-[11px] text-panel-text-2">
154
+ {showCarve ? "No other effects on this track." : "No effects on this track."}
155
+ </p>
156
+ ) : (
157
+ runs.map((run) => {
158
+ // How much of the preset is applied. Any node of the run carries
159
+ // it, and the first is the one the graph reads.
160
+ const rawAmount = run.items[0]?.node.presetAmount;
161
+ const amount = typeof rawAmount === "number" ? rawAmount : 1;
162
+ const runKey = `${run.preset}-${run.items[0]?.i ?? 0}`;
163
+ return (
164
+ <FxPresetRun
165
+ key={`preset-${run.preset}-${run.items[0]?.i}`}
166
+ run={run}
167
+ positions={positions}
168
+ totalNodes={chain.nodes.length}
169
+ automatedTargets={automatedTargets}
170
+ liveAutomationValues={liveAutomationValues}
171
+ onAutomateParam={onAutomateParam}
172
+ onRemoveParamAutomation={onRemoveParamAutomation}
173
+ openNode={openNode}
174
+ onToggleOpenNode={onToggleOpenNode}
175
+ disabled={disabled}
176
+ onUpdateNode={onUpdateNode}
177
+ onMoveNode={onMoveNode}
178
+ onRemoveNode={onRemoveNode}
179
+ onPreviewNode={onPreviewNode}
180
+ trackKind={trackKind}
181
+ collapsed={collapsedRuns.has(runKey)}
182
+ onToggleCollapse={() => onToggleCollapse(runKey)}
183
+ amount={amount}
184
+ onSetAmount={(v, persist = true) => {
185
+ if (persist && run.preset) trackPresetAmount(run.preset, v, { trackKind });
186
+ onSetRunAmount(run.items, v, persist);
187
+ }}
188
+ onRemoveRun={() => onRemoveRun(run.items, run.preset)}
189
+ automated={presetAutomated.has(run.preset ?? "")}
190
+ onAutomate={presetAutomateHandler(run.preset, amount)}
191
+ onRemoveAutomation={presetRemoveAutomationHandler(run.preset)}
192
+ />
193
+ );
194
+ })
195
+ )}
196
+ <p className="hf-fx-term hf-fx-term-out flex items-baseline gap-1.5 px-1.5 font-mono text-[9px] uppercase tracking-wide text-panel-text-2">
197
+ <span className="hf-fx-term-cap text-panel-text-1">Out</span>
198
+ <span>to mix</span>
199
+ </p>
200
+ </div>
201
+ );
202
+ }