@hyperframes/studio 0.7.63 → 0.7.65
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-BO2UXx-E.js → hyperframes-player-D2zuA3cx.js} +1 -1
- package/dist/assets/{index-C_7k3kwr.js → index-BqX4YLnH.js} +190 -190
- package/dist/assets/{index-_72wCKSP.js → index-DwwsYjuk.js} +1 -1
- package/dist/assets/{index-C0A0DlLk.js → index-hLCqiyjx.js} +1 -1
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/{domEditingLayers-2CKWGEHS.js → domEditingLayers-AT7G6F4L.js} +2 -1
- package/dist/domEditingLayers-AT7G6F4L.js.map +1 -0
- package/dist/index.html +1 -1
- package/dist/index.js +171 -53
- package/dist/index.js.map +1 -1
- package/dist/styles/tailwind-preset.js +2 -0
- package/dist/styles/tailwind-preset.js.map +1 -1
- package/package.json +9 -8
- package/src/components/StudioRightPanel.tsx +2 -2
- package/src/components/editor/keyframeRetime.test.ts +56 -17
- package/src/components/editor/keyframeRetime.ts +48 -4
- package/src/components/editor/manualEditingAvailability.ts +7 -0
- package/src/components/editor/manualEditsTypes.ts +1 -1
- package/src/components/nle/useTimelineEditCallbacks.test.ts +85 -0
- package/src/components/nle/useTimelineEditCallbacks.ts +52 -12
- package/src/components/panels/VariablesPanel.tsx +3 -1
- package/src/contexts/FileManagerContext.tsx +1 -0
- package/src/hooks/timelineEditingHelpers.test.ts +26 -0
- package/src/hooks/timelineEditingHelpers.ts +10 -1
- package/src/hooks/useGsapKeyframeOps.test.tsx +1 -0
- package/src/hooks/useGsapKeyframeOps.ts +2 -0
- package/src/hooks/useGsapPropertyDebounce.ts +1 -0
- package/src/hooks/useRazorSplit.ts +1 -0
- package/src/hooks/useTimelineEditing.test.tsx +1 -0
- package/src/hooks/useTimelineGroupEditing.ts +2 -0
- package/src/player/index.ts +0 -2
- package/src/utils/sdkCutover.familyGate.test.ts +47 -0
- package/src/utils/sdkCutover.test.ts +1 -0
- package/src/utils/sdkCutover.ts +95 -38
- package/src/utils/sdkCutoverPolicy.report.ts +3 -0
- package/src/utils/sdkCutoverPolicy.test.ts +38 -0
- package/src/utils/sdkCutoverPolicy.ts +98 -0
- /package/dist/{domEditingLayers-2CKWGEHS.js.map → chunk-PZ5AY32C.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as P}from"./index-
|
|
1
|
+
import{g as P}from"./index-BqX4YLnH.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
resolveDomEditSelection,
|
|
20
20
|
serializeDomEditTextFields
|
|
21
21
|
} from "./chunk-OBAG3GWK.js";
|
|
22
|
+
import "./chunk-PZ5AY32C.js";
|
|
22
23
|
export {
|
|
23
24
|
buildDefaultDomEditTextField,
|
|
24
25
|
buildDomEditPatchTarget,
|
|
@@ -40,4 +41,4 @@ export {
|
|
|
40
41
|
resolveDomEditSelection,
|
|
41
42
|
serializeDomEditTextFields
|
|
42
43
|
};
|
|
43
|
-
//# sourceMappingURL=domEditingLayers-
|
|
44
|
+
//# sourceMappingURL=domEditingLayers-AT7G6F4L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
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-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BqX4YLnH.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-Ceyz8Qt2.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,9 @@ import {
|
|
|
24
24
|
serializeDomEditTextFields,
|
|
25
25
|
setCompositionSourceMap
|
|
26
26
|
} from "./chunk-OBAG3GWK.js";
|
|
27
|
+
import {
|
|
28
|
+
__export
|
|
29
|
+
} from "./chunk-PZ5AY32C.js";
|
|
27
30
|
|
|
28
31
|
// src/components/EditorShell.tsx
|
|
29
32
|
import { useCallback as useCallback45 } from "react";
|
|
@@ -2952,6 +2955,7 @@ function useFileManagerContextOptional() {
|
|
|
2952
2955
|
}
|
|
2953
2956
|
function FileManagerProvider({
|
|
2954
2957
|
value: {
|
|
2958
|
+
// fallow-ignore-next-line code-duplication
|
|
2955
2959
|
editingFile,
|
|
2956
2960
|
setEditingFile,
|
|
2957
2961
|
projectDir,
|
|
@@ -6527,6 +6531,48 @@ function clampGroupMoveDelta(rawDelta, memberStarts) {
|
|
|
6527
6531
|
return rawDelta < minDelta ? minDelta : rawDelta;
|
|
6528
6532
|
}
|
|
6529
6533
|
|
|
6534
|
+
// src/components/editor/manualEditingAvailability.ts
|
|
6535
|
+
var manualEditingAvailability_exports = {};
|
|
6536
|
+
__export(manualEditingAvailability_exports, {
|
|
6537
|
+
STUDIO_BLOCKS_PANEL_ENABLED: () => STUDIO_BLOCKS_PANEL_ENABLED,
|
|
6538
|
+
STUDIO_FLAT_INSPECTOR_ENABLED: () => STUDIO_FLAT_INSPECTOR_ENABLED,
|
|
6539
|
+
STUDIO_GSAP_PANEL_ENABLED: () => STUDIO_GSAP_PANEL_ENABLED,
|
|
6540
|
+
STUDIO_INSPECTOR_PANELS_ENABLED: () => STUDIO_INSPECTOR_PANELS_ENABLED,
|
|
6541
|
+
STUDIO_KEYFRAMES_ENABLED: () => STUDIO_KEYFRAMES_ENABLED,
|
|
6542
|
+
STUDIO_MANUAL_EDITING_DISABLED_TITLE: () => STUDIO_MANUAL_EDITING_DISABLED_TITLE,
|
|
6543
|
+
STUDIO_PREVIEW_MANUAL_EDITING_ENABLED: () => STUDIO_PREVIEW_MANUAL_EDITING_ENABLED,
|
|
6544
|
+
STUDIO_PREVIEW_SELECTION_ENABLED: () => STUDIO_PREVIEW_SELECTION_ENABLED,
|
|
6545
|
+
STUDIO_RAZOR_TOOL_ENABLED: () => STUDIO_RAZOR_TOOL_ENABLED,
|
|
6546
|
+
STUDIO_SDK_CUTOVER_ENABLED: () => STUDIO_SDK_CUTOVER_ENABLED,
|
|
6547
|
+
STUDIO_SDK_CUTOVER_FAMILIES: () => STUDIO_SDK_CUTOVER_FAMILIES,
|
|
6548
|
+
STUDIO_SDK_RESOLVER_SHADOW_ENABLED: () => STUDIO_SDK_RESOLVER_SHADOW_ENABLED,
|
|
6549
|
+
resolveStudioBooleanEnvFlag: () => resolveStudioBooleanEnvFlag
|
|
6550
|
+
});
|
|
6551
|
+
|
|
6552
|
+
// src/utils/sdkCutoverPolicy.ts
|
|
6553
|
+
var STUDIO_SDK_OPERATION_FAMILIES = [
|
|
6554
|
+
"dom",
|
|
6555
|
+
"timing",
|
|
6556
|
+
"gsap-animation",
|
|
6557
|
+
"gsap-keyframe",
|
|
6558
|
+
"lifecycle"
|
|
6559
|
+
];
|
|
6560
|
+
function resolveEnabledSdkFamilies(env2, masterEnabled) {
|
|
6561
|
+
if (!masterEnabled) return /* @__PURE__ */ new Set();
|
|
6562
|
+
const raw = env2["VITE_STUDIO_SDK_CUTOVER_FAMILIES"];
|
|
6563
|
+
if (typeof raw !== "string" || raw.trim() === "") return /* @__PURE__ */ new Set();
|
|
6564
|
+
const requested = raw.split(",").map((family) => family.trim()).filter(Boolean);
|
|
6565
|
+
const known = new Set(STUDIO_SDK_OPERATION_FAMILIES);
|
|
6566
|
+
const unknown = requested.filter((family) => !known.has(family));
|
|
6567
|
+
if (unknown.length > 0) {
|
|
6568
|
+
throw new Error(`Unknown Studio SDK cutover families: ${unknown.join(", ")}`);
|
|
6569
|
+
}
|
|
6570
|
+
return new Set(requested);
|
|
6571
|
+
}
|
|
6572
|
+
function isSdkFamilyEnabled(masterEnabled, configured, family) {
|
|
6573
|
+
return masterEnabled && (configured?.has(family) ?? true);
|
|
6574
|
+
}
|
|
6575
|
+
|
|
6530
6576
|
// src/components/editor/manualEditingAvailability.ts
|
|
6531
6577
|
var STUDIO_PREVIEW_MANUAL_DRAGGING_ENV = "VITE_STUDIO_ENABLE_PREVIEW_MANUAL_DRAGGING";
|
|
6532
6578
|
var STUDIO_INSPECTOR_PANELS_ENV = "VITE_STUDIO_ENABLE_INSPECTOR_PANELS";
|
|
@@ -6582,6 +6628,10 @@ var STUDIO_SDK_CUTOVER_ENABLED = resolveStudioBooleanEnvFlag(
|
|
|
6582
6628
|
["VITE_STUDIO_SDK_CUTOVER_ENABLED"],
|
|
6583
6629
|
false
|
|
6584
6630
|
);
|
|
6631
|
+
var STUDIO_SDK_CUTOVER_FAMILIES = resolveEnabledSdkFamilies(
|
|
6632
|
+
env,
|
|
6633
|
+
STUDIO_SDK_CUTOVER_ENABLED
|
|
6634
|
+
);
|
|
6585
6635
|
var STUDIO_SDK_RESOLVER_SHADOW_ENABLED = resolveStudioBooleanEnvFlag(
|
|
6586
6636
|
env,
|
|
6587
6637
|
["VITE_STUDIO_SDK_RESOLVER_SHADOW_ENABLED"],
|
|
@@ -7911,6 +7961,12 @@ function findTimelineElementInIframe(iframe, element, activeCompositionPath = nu
|
|
|
7911
7961
|
try {
|
|
7912
7962
|
const doc = iframe?.contentDocument;
|
|
7913
7963
|
if (!doc) return null;
|
|
7964
|
+
if (element.kind === "composition" && element.compositionSrc) {
|
|
7965
|
+
return findElementForTimelineElement(doc, element, {
|
|
7966
|
+
activeCompositionPath,
|
|
7967
|
+
isMasterView: true
|
|
7968
|
+
});
|
|
7969
|
+
}
|
|
7914
7970
|
return findElementForSelection(
|
|
7915
7971
|
doc,
|
|
7916
7972
|
{
|
|
@@ -17822,7 +17878,7 @@ function OffCanvasIndicators({
|
|
|
17822
17878
|
const selectOffCanvas = async () => {
|
|
17823
17879
|
const el = elements.current.get(r.key);
|
|
17824
17880
|
if (!el) return;
|
|
17825
|
-
const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-
|
|
17881
|
+
const { resolveDomEditSelection: resolveDomEditSelection2 } = await import("./domEditingLayers-AT7G6F4L.js");
|
|
17826
17882
|
const acp = activeCompositionPathRef.current ?? "index.html";
|
|
17827
17883
|
const sel = await resolveDomEditSelection2(el, {
|
|
17828
17884
|
activeCompositionPath: acp,
|
|
@@ -17864,7 +17920,7 @@ import {
|
|
|
17864
17920
|
STUDIO_WIDTH_PROP,
|
|
17865
17921
|
STUDIO_HEIGHT_PROP,
|
|
17866
17922
|
STUDIO_MANUAL_EDIT_GESTURE_ATTR
|
|
17867
|
-
} from "@hyperframes/
|
|
17923
|
+
} from "@hyperframes/core/editing/draft-markers";
|
|
17868
17924
|
var STUDIO_ROTATION_PROP = "--hf-studio-rotation";
|
|
17869
17925
|
var STUDIO_PATH_OFFSET_ATTR = "data-hf-studio-path-offset";
|
|
17870
17926
|
var STUDIO_BOX_SIZE_ATTR = "data-hf-studio-box-size";
|
|
@@ -24804,6 +24860,20 @@ async function persistSdkSerialize(buildAfter, targetPath, originalContent, deps
|
|
|
24804
24860
|
}
|
|
24805
24861
|
|
|
24806
24862
|
// src/utils/sdkCutover.ts
|
|
24863
|
+
function sdkFamilyEnabled(family) {
|
|
24864
|
+
const configured = Object.prototype.hasOwnProperty.call(
|
|
24865
|
+
manualEditingAvailability_exports,
|
|
24866
|
+
"STUDIO_SDK_CUTOVER_FAMILIES"
|
|
24867
|
+
) ? STUDIO_SDK_CUTOVER_FAMILIES : void 0;
|
|
24868
|
+
return isSdkFamilyEnabled(STUDIO_SDK_CUTOVER_ENABLED, configured, family);
|
|
24869
|
+
}
|
|
24870
|
+
function trackCutoverResult(result, context) {
|
|
24871
|
+
if (result.status === "committed") {
|
|
24872
|
+
trackStudioEvent("sdk_cutover_success", context);
|
|
24873
|
+
} else if (result.status === "failed") {
|
|
24874
|
+
trackStudioEvent("sdk_cutover_failed", { ...context, error: result.error.message });
|
|
24875
|
+
}
|
|
24876
|
+
}
|
|
24807
24877
|
function wrongCompositionFile(deps, targetPath) {
|
|
24808
24878
|
return deps.compositionPath != null && targetPath !== deps.compositionPath;
|
|
24809
24879
|
}
|
|
@@ -24812,7 +24882,7 @@ function gsapReadSource(deps, targetPath) {
|
|
|
24812
24882
|
return read ? () => read(targetPath) : void 0;
|
|
24813
24883
|
}
|
|
24814
24884
|
async function sdkCutoverPersist(selection, ops, originalContent, targetPath, sdkSession, deps, options) {
|
|
24815
|
-
if (!shouldUseSdkCutover(
|
|
24885
|
+
if (!shouldUseSdkCutover(sdkFamilyEnabled("dom"), !!sdkSession, selection.hfId, ops))
|
|
24816
24886
|
return declinedCutover("ineligible_operation");
|
|
24817
24887
|
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
24818
24888
|
const hfId = selection.hfId;
|
|
@@ -24832,11 +24902,7 @@ async function sdkCutoverPersist(selection, ops, originalContent, targetPath, sd
|
|
|
24832
24902
|
},
|
|
24833
24903
|
options
|
|
24834
24904
|
);
|
|
24835
|
-
|
|
24836
|
-
trackStudioEvent("sdk_cutover_success", { hfId, opCount: ops.length });
|
|
24837
|
-
} else if (result.status === "failed") {
|
|
24838
|
-
trackStudioEvent("sdk_cutover_failed", { hfId, error: result.error.message });
|
|
24839
|
-
}
|
|
24905
|
+
trackCutoverResult(result, { hfId, opCount: ops.length });
|
|
24840
24906
|
return result;
|
|
24841
24907
|
}
|
|
24842
24908
|
async function sdkTimingPersist(hfId, targetPath, timingUpdate, sdkSession, deps, options) {
|
|
@@ -24848,7 +24914,7 @@ async function sdkTimingPersist(hfId, targetPath, timingUpdate, sdkSession, deps
|
|
|
24848
24914
|
timingSrc ? () => timingSrc(targetPath) : void 0,
|
|
24849
24915
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
24850
24916
|
);
|
|
24851
|
-
if (!
|
|
24917
|
+
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled");
|
|
24852
24918
|
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
24853
24919
|
if (!sdkSession.getElement(hfId)) return declinedCutover("target_not_found");
|
|
24854
24920
|
if (wrongCompositionFile(deps, targetPath)) return declinedCutover("wrong_composition_file");
|
|
@@ -24863,11 +24929,7 @@ async function sdkTimingPersist(hfId, targetPath, timingUpdate, sdkSession, deps
|
|
|
24863
24929
|
options,
|
|
24864
24930
|
serializedBefore
|
|
24865
24931
|
);
|
|
24866
|
-
|
|
24867
|
-
trackStudioEvent("sdk_cutover_success", { hfId, opCount: 1 });
|
|
24868
|
-
} else if (result.status === "failed") {
|
|
24869
|
-
trackStudioEvent("sdk_cutover_failed", { hfId, error: result.error.message });
|
|
24870
|
-
}
|
|
24932
|
+
trackCutoverResult(result, { hfId, opCount: 1 });
|
|
24871
24933
|
return result;
|
|
24872
24934
|
} catch (error) {
|
|
24873
24935
|
const failed2 = { status: "failed", error: asCutoverError(error) };
|
|
@@ -24886,7 +24948,7 @@ async function sdkTimingBatchPersist(changes, targetPath, sdkSession, deps, opti
|
|
|
24886
24948
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
24887
24949
|
);
|
|
24888
24950
|
}
|
|
24889
|
-
if (!
|
|
24951
|
+
if (!sdkFamilyEnabled("timing")) return declinedCutover("feature_disabled");
|
|
24890
24952
|
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
24891
24953
|
if (wrongCompositionFile(deps, targetPath)) return declinedCutover("wrong_composition_file");
|
|
24892
24954
|
if (changes.some((change) => !sdkSession.getElement(change.hfId)))
|
|
@@ -24944,10 +25006,11 @@ function sdkGsapTweenPersist(targetPath, op, sdkSession, deps, options) {
|
|
|
24944
25006
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
24945
25007
|
);
|
|
24946
25008
|
}
|
|
24947
|
-
if (!
|
|
25009
|
+
if (!sdkFamilyEnabled("gsap-animation"))
|
|
25010
|
+
return Promise.resolve(declinedCutover("feature_disabled"));
|
|
24948
25011
|
if (op.kind === "add" && sdkSession && !sdkSession.getElement(op.target))
|
|
24949
25012
|
return Promise.resolve(declinedCutover("target_not_found"));
|
|
24950
|
-
return dispatchGsapOpAndPersist(targetPath, sdkSession, deps, options, (s) => {
|
|
25013
|
+
return dispatchGsapOpAndPersist("gsap-animation", targetPath, sdkSession, deps, options, (s) => {
|
|
24951
25014
|
s.batch(() => {
|
|
24952
25015
|
if (op.kind === "add") {
|
|
24953
25016
|
s.addGsapTween(op.target, op.spec);
|
|
@@ -24959,7 +25022,7 @@ function sdkGsapTweenPersist(targetPath, op, sdkSession, deps, options) {
|
|
|
24959
25022
|
});
|
|
24960
25023
|
});
|
|
24961
25024
|
}
|
|
24962
|
-
async function dispatchGsapOpAndPersist(targetPath, sdkSession, deps, options, dispatch, resolverTarget) {
|
|
25025
|
+
async function dispatchGsapOpAndPersist(family, targetPath, sdkSession, deps, options, dispatch, resolverTarget) {
|
|
24963
25026
|
if (resolverTarget) {
|
|
24964
25027
|
void recordAnimationResolverParity(
|
|
24965
25028
|
sdkSession,
|
|
@@ -24969,7 +25032,7 @@ async function dispatchGsapOpAndPersist(targetPath, sdkSession, deps, options, d
|
|
|
24969
25032
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
24970
25033
|
);
|
|
24971
25034
|
}
|
|
24972
|
-
if (!
|
|
25035
|
+
if (!sdkFamilyEnabled(family)) return declinedCutover("feature_disabled");
|
|
24973
25036
|
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
24974
25037
|
if (wrongCompositionFile(deps, targetPath)) return declinedCutover("wrong_composition_file");
|
|
24975
25038
|
const session = sdkSession;
|
|
@@ -24998,6 +25061,7 @@ async function dispatchGsapOpAndPersist(targetPath, sdkSession, deps, options, d
|
|
|
24998
25061
|
}
|
|
24999
25062
|
function sdkGsapKeyframePersist(targetPath, animationId, position, value, sdkSession, deps, options) {
|
|
25000
25063
|
return dispatchGsapOpAndPersist(
|
|
25064
|
+
"gsap-keyframe",
|
|
25001
25065
|
targetPath,
|
|
25002
25066
|
sdkSession,
|
|
25003
25067
|
deps,
|
|
@@ -25008,6 +25072,7 @@ function sdkGsapKeyframePersist(targetPath, animationId, position, value, sdkSes
|
|
|
25008
25072
|
}
|
|
25009
25073
|
function sdkGsapRemoveKeyframePersist(targetPath, animationId, percentage, sdkSession, deps, options) {
|
|
25010
25074
|
return dispatchGsapOpAndPersist(
|
|
25075
|
+
"gsap-keyframe",
|
|
25011
25076
|
targetPath,
|
|
25012
25077
|
sdkSession,
|
|
25013
25078
|
deps,
|
|
@@ -25018,6 +25083,7 @@ function sdkGsapRemoveKeyframePersist(targetPath, animationId, percentage, sdkSe
|
|
|
25018
25083
|
}
|
|
25019
25084
|
function sdkGsapRemovePropertyPersist(targetPath, animationId, property, from, sdkSession, deps, options) {
|
|
25020
25085
|
return dispatchGsapOpAndPersist(
|
|
25086
|
+
"gsap-animation",
|
|
25021
25087
|
targetPath,
|
|
25022
25088
|
sdkSession,
|
|
25023
25089
|
deps,
|
|
@@ -25028,6 +25094,7 @@ function sdkGsapRemovePropertyPersist(targetPath, animationId, property, from, s
|
|
|
25028
25094
|
}
|
|
25029
25095
|
function sdkGsapDeleteAllForSelectorPersist(targetPath, selector, sdkSession, deps, options) {
|
|
25030
25096
|
return dispatchGsapOpAndPersist(
|
|
25097
|
+
"gsap-animation",
|
|
25031
25098
|
targetPath,
|
|
25032
25099
|
sdkSession,
|
|
25033
25100
|
deps,
|
|
@@ -25037,6 +25104,7 @@ function sdkGsapDeleteAllForSelectorPersist(targetPath, selector, sdkSession, de
|
|
|
25037
25104
|
}
|
|
25038
25105
|
function sdkGsapRemoveAllKeyframesPersist(targetPath, animationId, sdkSession, deps, options) {
|
|
25039
25106
|
return dispatchGsapOpAndPersist(
|
|
25107
|
+
"gsap-keyframe",
|
|
25040
25108
|
targetPath,
|
|
25041
25109
|
sdkSession,
|
|
25042
25110
|
deps,
|
|
@@ -25047,6 +25115,7 @@ function sdkGsapRemoveAllKeyframesPersist(targetPath, animationId, sdkSession, d
|
|
|
25047
25115
|
}
|
|
25048
25116
|
function sdkGsapConvertToKeyframesPersist(targetPath, animationId, resolvedFromValues, sdkSession, deps, options) {
|
|
25049
25117
|
return dispatchGsapOpAndPersist(
|
|
25118
|
+
"gsap-keyframe",
|
|
25050
25119
|
targetPath,
|
|
25051
25120
|
sdkSession,
|
|
25052
25121
|
deps,
|
|
@@ -25055,6 +25124,9 @@ function sdkGsapConvertToKeyframesPersist(targetPath, animationId, resolvedFromV
|
|
|
25055
25124
|
{ animationId, opLabel: "convertToKeyframes" }
|
|
25056
25125
|
);
|
|
25057
25126
|
}
|
|
25127
|
+
function keyframesPayload(targetSelector, position, duration, keyframes, ease) {
|
|
25128
|
+
return { targetSelector, position, duration, keyframes, ...ease ? { ease } : {} };
|
|
25129
|
+
}
|
|
25058
25130
|
function dispatchWithKeyframes(s, payload, animationId) {
|
|
25059
25131
|
if (animationId !== void 0) {
|
|
25060
25132
|
s.dispatch({ type: "replaceWithKeyframes", animationId, ...payload });
|
|
@@ -25062,38 +25134,50 @@ function dispatchWithKeyframes(s, payload, animationId) {
|
|
|
25062
25134
|
s.dispatch({ type: "addWithKeyframes", ...payload });
|
|
25063
25135
|
}
|
|
25064
25136
|
}
|
|
25137
|
+
function persistKeyframesOperation(input) {
|
|
25138
|
+
const payload = keyframesPayload(
|
|
25139
|
+
input.targetSelector,
|
|
25140
|
+
input.position,
|
|
25141
|
+
input.duration,
|
|
25142
|
+
input.keyframes,
|
|
25143
|
+
input.ease
|
|
25144
|
+
);
|
|
25145
|
+
return dispatchGsapOpAndPersist(
|
|
25146
|
+
"gsap-keyframe",
|
|
25147
|
+
input.targetPath,
|
|
25148
|
+
input.sdkSession,
|
|
25149
|
+
input.deps,
|
|
25150
|
+
input.options,
|
|
25151
|
+
(session) => dispatchWithKeyframes(session, payload, input.animationId),
|
|
25152
|
+
input.animationId ? { animationId: input.animationId, opLabel: "replaceWithKeyframes" } : void 0
|
|
25153
|
+
);
|
|
25154
|
+
}
|
|
25065
25155
|
function sdkAddWithKeyframesPersist(targetPath, targetSelector, position, duration, keyframes, ease, sdkSession, deps, options) {
|
|
25066
|
-
|
|
25156
|
+
return persistKeyframesOperation({
|
|
25157
|
+
targetPath,
|
|
25067
25158
|
targetSelector,
|
|
25068
25159
|
position,
|
|
25069
25160
|
duration,
|
|
25070
25161
|
keyframes,
|
|
25071
|
-
|
|
25072
|
-
};
|
|
25073
|
-
return dispatchGsapOpAndPersist(
|
|
25074
|
-
targetPath,
|
|
25162
|
+
ease,
|
|
25075
25163
|
sdkSession,
|
|
25076
25164
|
deps,
|
|
25077
|
-
options
|
|
25078
|
-
|
|
25079
|
-
);
|
|
25165
|
+
options
|
|
25166
|
+
});
|
|
25080
25167
|
}
|
|
25081
25168
|
function sdkReplaceWithKeyframesPersist(targetPath, animationId, targetSelector, position, duration, keyframes, ease, sdkSession, deps, options) {
|
|
25082
|
-
|
|
25169
|
+
return persistKeyframesOperation({
|
|
25170
|
+
targetPath,
|
|
25171
|
+
animationId,
|
|
25083
25172
|
targetSelector,
|
|
25084
25173
|
position,
|
|
25085
25174
|
duration,
|
|
25086
25175
|
keyframes,
|
|
25087
|
-
|
|
25088
|
-
};
|
|
25089
|
-
return dispatchGsapOpAndPersist(
|
|
25090
|
-
targetPath,
|
|
25176
|
+
ease,
|
|
25091
25177
|
sdkSession,
|
|
25092
25178
|
deps,
|
|
25093
|
-
options
|
|
25094
|
-
|
|
25095
|
-
{ animationId, opLabel: "replaceWithKeyframes" }
|
|
25096
|
-
);
|
|
25179
|
+
options
|
|
25180
|
+
});
|
|
25097
25181
|
}
|
|
25098
25182
|
async function sdkDeletePersist(hfId, originalContent, targetPath, sdkSession, deps) {
|
|
25099
25183
|
void recordResolverParity(
|
|
@@ -25103,7 +25187,7 @@ async function sdkDeletePersist(hfId, originalContent, targetPath, sdkSession, d
|
|
|
25103
25187
|
() => Promise.resolve(originalContent),
|
|
25104
25188
|
{ targetPath, compositionPath: deps.compositionPath }
|
|
25105
25189
|
);
|
|
25106
|
-
if (!
|
|
25190
|
+
if (!sdkFamilyEnabled("lifecycle")) return declinedCutover("feature_disabled");
|
|
25107
25191
|
if (!sdkSession) return declinedCutover("session_unavailable");
|
|
25108
25192
|
if (!sdkSession.getElement(hfId)) return declinedCutover("target_not_found");
|
|
25109
25193
|
if (wrongCompositionFile(deps, targetPath)) return declinedCutover("wrong_composition_file");
|
|
@@ -25115,11 +25199,7 @@ async function sdkDeletePersist(hfId, originalContent, targetPath, sdkSession, d
|
|
|
25115
25199
|
(session) => session.removeElement(hfId),
|
|
25116
25200
|
{ label: "Delete element" }
|
|
25117
25201
|
);
|
|
25118
|
-
|
|
25119
|
-
trackStudioEvent("sdk_cutover_success", { hfId, opCount: 1 });
|
|
25120
|
-
} else if (result.status === "failed") {
|
|
25121
|
-
trackStudioEvent("sdk_cutover_failed", { hfId, error: result.error.message });
|
|
25122
|
-
}
|
|
25202
|
+
trackCutoverResult(result, { hfId, opCount: 1 });
|
|
25123
25203
|
return result;
|
|
25124
25204
|
}
|
|
25125
25205
|
|
|
@@ -26954,13 +27034,39 @@ function usePopulateKeyframeCacheForFile(projectId, sourceFile, version, iframeR
|
|
|
26954
27034
|
// src/components/editor/keyframeRetime.ts
|
|
26955
27035
|
var NOOP_EPSILON_PCT2 = 0.1;
|
|
26956
27036
|
var EPSILON_TIME = 1e-4;
|
|
27037
|
+
var MIN_TWEEN_DURATION = 0.01;
|
|
26957
27038
|
var round33 = (n) => Math.round(n * 1e3) / 1e3;
|
|
26958
27039
|
var round1 = (n) => Math.round(n * 10) / 10;
|
|
26959
27040
|
var clamp4 = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
|
|
27041
|
+
function resolveFlatTweenBoundaryRetime(opts) {
|
|
27042
|
+
const { keyframeCount, draggedTweenPct, tweenStart, tweenEnd, dropAbsTime } = opts;
|
|
27043
|
+
if (keyframeCount > 0) return null;
|
|
27044
|
+
if (draggedTweenPct !== 0 && draggedTweenPct !== 100) return { kind: "noop" };
|
|
27045
|
+
const draggedTime = draggedTweenPct === 0 ? tweenStart : tweenEnd;
|
|
27046
|
+
if (Math.abs(dropAbsTime - draggedTime) <= EPSILON_TIME) return { kind: "noop" };
|
|
27047
|
+
const newStart = draggedTweenPct === 0 ? dropAbsTime : tweenStart;
|
|
27048
|
+
const newEnd = draggedTweenPct === 100 ? dropAbsTime : tweenEnd;
|
|
27049
|
+
const newDuration = newEnd - newStart;
|
|
27050
|
+
if (newDuration < MIN_TWEEN_DURATION) return { kind: "noop" };
|
|
27051
|
+
return {
|
|
27052
|
+
kind: "resize",
|
|
27053
|
+
position: round33(newStart),
|
|
27054
|
+
duration: round33(newDuration),
|
|
27055
|
+
pctRemap: []
|
|
27056
|
+
};
|
|
27057
|
+
}
|
|
26960
27058
|
function resolveKeyframeRetime(opts) {
|
|
26961
27059
|
const { keyframes, draggedTweenPct, tweenStart, tweenDuration, dropAbsTime } = opts;
|
|
26962
27060
|
if (tweenDuration <= 0) return { kind: "noop" };
|
|
26963
27061
|
const tweenEnd = tweenStart + tweenDuration;
|
|
27062
|
+
const flatBoundary = resolveFlatTweenBoundaryRetime({
|
|
27063
|
+
keyframeCount: keyframes.length,
|
|
27064
|
+
draggedTweenPct,
|
|
27065
|
+
tweenStart,
|
|
27066
|
+
tweenEnd,
|
|
27067
|
+
dropAbsTime
|
|
27068
|
+
});
|
|
27069
|
+
if (flatBoundary) return flatBoundary;
|
|
26964
27070
|
if (dropAbsTime >= tweenStart - EPSILON_TIME && dropAbsTime <= tweenEnd + EPSILON_TIME) {
|
|
26965
27071
|
const toTweenPct = clamp4((dropAbsTime - tweenStart) / tweenDuration * 100, 0, 100);
|
|
26966
27072
|
if (Math.abs(toTweenPct - draggedTweenPct) < NOOP_EPSILON_PCT2) return { kind: "noop" };
|
|
@@ -26969,7 +27075,7 @@ function resolveKeyframeRetime(opts) {
|
|
|
26969
27075
|
if (keyframes.length === 0) return { kind: "noop" };
|
|
26970
27076
|
const newStart = Math.min(dropAbsTime, tweenStart);
|
|
26971
27077
|
const newEnd = Math.max(dropAbsTime, tweenEnd);
|
|
26972
|
-
const newDuration = Math.max(
|
|
27078
|
+
const newDuration = Math.max(MIN_TWEEN_DURATION, newEnd - newStart);
|
|
26973
27079
|
let draggedIdx = 0;
|
|
26974
27080
|
let best = Infinity;
|
|
26975
27081
|
keyframes.forEach((kf, i) => {
|
|
@@ -26992,6 +27098,14 @@ function resolveKeyframeRetime(opts) {
|
|
|
26992
27098
|
}
|
|
26993
27099
|
|
|
26994
27100
|
// src/components/nle/useTimelineEditCallbacks.ts
|
|
27101
|
+
function resolveTimelineKeyframeTarget(pct, keyframes, animations) {
|
|
27102
|
+
const kf = keyframes.find((item) => Math.abs(item.percentage - pct) < 0.2);
|
|
27103
|
+
if (!kf) return null;
|
|
27104
|
+
const group = kf?.propertyGroup;
|
|
27105
|
+
const candidates = group ? animations.filter((animation2) => animation2.propertyGroup === group) : animations.filter((animation2) => !animation2.propertyGroup);
|
|
27106
|
+
const animation = candidates.length === 1 ? candidates[0] : void 0;
|
|
27107
|
+
return animation ? { animId: animation.id, tweenPct: kf.tweenPercentage ?? pct } : null;
|
|
27108
|
+
}
|
|
26995
27109
|
function useTimelineEditCallbacks({
|
|
26996
27110
|
handleTimelineElementMove,
|
|
26997
27111
|
handleTimelineElementsMove,
|
|
@@ -27020,10 +27134,7 @@ function useTimelineEditCallbacks({
|
|
|
27020
27134
|
// fallow-ignore-next-line complexity
|
|
27021
27135
|
(pct) => {
|
|
27022
27136
|
const cached2 = usePlayerStore.getState().keyframeCache.get(domEditSelection?.id ?? "");
|
|
27023
|
-
|
|
27024
|
-
const group = kf?.propertyGroup;
|
|
27025
|
-
const anim = (group ? selectedGsapAnimations.find((a) => a.propertyGroup === group) : void 0) ?? selectedGsapAnimations.find((a) => a.keyframes);
|
|
27026
|
-
return anim ? { animId: anim.id, tweenPct: kf?.tweenPercentage ?? pct } : null;
|
|
27137
|
+
return resolveTimelineKeyframeTarget(pct, cached2?.keyframes ?? [], selectedGsapAnimations);
|
|
27027
27138
|
},
|
|
27028
27139
|
[domEditSelection?.id, selectedGsapAnimations]
|
|
27029
27140
|
);
|
|
@@ -27087,12 +27198,19 @@ function useTimelineEditCallbacks({
|
|
|
27087
27198
|
if (decision.kind === "move" && decision.toTweenPct != null) {
|
|
27088
27199
|
handleGsapMoveKeyframe(target.animId, target.tweenPct, decision.toTweenPct);
|
|
27089
27200
|
} else if (decision.kind === "resize" && decision.pctRemap && decision.position != null && decision.duration != null) {
|
|
27090
|
-
|
|
27091
|
-
|
|
27092
|
-
|
|
27093
|
-
|
|
27094
|
-
|
|
27095
|
-
|
|
27201
|
+
if (anim.keyframes) {
|
|
27202
|
+
handleGsapResizeKeyframedTween(
|
|
27203
|
+
target.animId,
|
|
27204
|
+
decision.position,
|
|
27205
|
+
decision.duration,
|
|
27206
|
+
decision.pctRemap
|
|
27207
|
+
);
|
|
27208
|
+
} else {
|
|
27209
|
+
handleGsapUpdateMeta(target.animId, {
|
|
27210
|
+
position: decision.position,
|
|
27211
|
+
duration: decision.duration
|
|
27212
|
+
});
|
|
27213
|
+
}
|
|
27096
27214
|
}
|
|
27097
27215
|
},
|
|
27098
27216
|
onChangeKeyframeEase: (_elId, _pct, ease) => {
|