@remotion/studio-server 4.0.493 → 4.0.494

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.
@@ -10,6 +10,7 @@ export type KeyframeOperation = {
10
10
  } | {
11
11
  type: 'remove';
12
12
  frame: number;
13
+ valueWhenLastKeyframeDeleted: unknown | null;
13
14
  } | {
14
15
  type: 'settings';
15
16
  clamping: {
@@ -682,7 +682,7 @@ const addKeyframe = ({ expression, key, frame, value, schema, videoConfigValues,
682
682
  },
683
683
  };
684
684
  };
685
- const removeKeyframe = ({ expression, frame, videoConfigValues, }) => {
685
+ const removeKeyframe = ({ expression, frame, videoConfigValues, valueWhenLastKeyframeDeleted, }) => {
686
686
  const existing = getInterpolationExpression(expression, videoConfigValues);
687
687
  if (!existing) {
688
688
  throw new Error('Cannot remove keyframe from non-interpolated expression');
@@ -694,7 +694,9 @@ const removeKeyframe = ({ expression, frame, videoConfigValues, }) => {
694
694
  const nextKeyframes = existing.keyframes.filter((_keyframe, index) => index !== keyframeIndex);
695
695
  if (nextKeyframes.length === 0) {
696
696
  return {
697
- expression: existing.keyframes[keyframeIndex].output,
697
+ expression: valueWhenLastKeyframeDeleted === null
698
+ ? existing.keyframes[keyframeIndex].output
699
+ : (0, update_nested_prop_1.parseValueExpression)(valueWhenLastKeyframeDeleted),
698
700
  introduced: noIntroducedIdentifiers,
699
701
  };
700
702
  }
@@ -828,6 +830,7 @@ const applyKeyframeOperation = ({ expression, key, operation, schema, videoConfi
828
830
  expression,
829
831
  frame: operation.frame,
830
832
  videoConfigValues,
833
+ valueWhenLastKeyframeDeleted: operation.valueWhenLastKeyframeDeleted,
831
834
  });
832
835
  };
833
836
  const getExpressionFromJsxAttribute = (attr) => {
@@ -82,11 +82,35 @@ const parseVideoConfigNumericExpression = ({ node, videoConfigValues, }) => {
82
82
  if (videoConfigValue !== null) {
83
83
  return { type: 'video-config-value', ...videoConfigValue };
84
84
  }
85
- if (node.type !== 'BinaryExpression' || node.operator !== '*') {
85
+ if (node.type !== 'BinaryExpression') {
86
86
  return null;
87
87
  }
88
88
  const left = node.left;
89
89
  const right = node.right;
90
+ if (node.operator === '-') {
91
+ const minuend = getVideoConfigValue({
92
+ node: left,
93
+ videoConfigValues,
94
+ });
95
+ const subtrahend = getNumericLiteral(right);
96
+ if (minuend === null || subtrahend === null) {
97
+ return null;
98
+ }
99
+ const resolvedValue = minuend.value - subtrahend;
100
+ if (!Number.isFinite(resolvedValue)) {
101
+ return null;
102
+ }
103
+ return {
104
+ type: 'video-config-subtraction',
105
+ identifier: minuend.identifier,
106
+ minuend: minuend.value,
107
+ subtrahend,
108
+ value: resolvedValue,
109
+ };
110
+ }
111
+ if (node.operator !== '*') {
112
+ return null;
113
+ }
90
114
  const leftNumber = getNumericLiteral(left);
91
115
  const rightNumber = getNumericLiteral(right);
92
116
  const leftVideoConfig = getVideoConfigValue({
@@ -136,6 +160,13 @@ const updateVideoConfigNumericExpression = ({ expression, value, }) => {
136
160
  ? b.identifier(expression.identifier)
137
161
  : numericExpression(value);
138
162
  }
163
+ if (expression.type === 'video-config-subtraction') {
164
+ const subtrahend = expression.minuend - value;
165
+ if (!Number.isFinite(subtrahend)) {
166
+ return numericExpression(value);
167
+ }
168
+ return b.binaryExpression('-', b.identifier(expression.identifier), numericExpression(subtrahend));
169
+ }
139
170
  if (expression.type !== 'video-config-multiplication' || value === 0) {
140
171
  return numericExpression(value);
141
172
  }
@@ -97,13 +97,17 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
97
97
  input: output,
98
98
  nodePath: firstSequenceKeyframe.nodePath.nodePath,
99
99
  videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
100
- updates: keyframeGroup.map((keyframe) => ({
101
- key: keyframe.key,
102
- operation: {
103
- type: 'remove',
104
- frame: keyframe.frame,
105
- },
106
- })),
100
+ updates: keyframeGroup.map((keyframe) => {
101
+ var _a;
102
+ return ({
103
+ key: keyframe.key,
104
+ operation: {
105
+ type: 'remove',
106
+ frame: keyframe.frame,
107
+ valueWhenLastKeyframeDeleted: (_a = keyframe.valueWhenLastKeyframeDeleted) !== null && _a !== void 0 ? _a : null,
108
+ },
109
+ });
110
+ }),
107
111
  });
108
112
  output = result.output;
109
113
  firstLogLine = Math.min(firstLogLine, result.logLine);
@@ -128,13 +132,17 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
128
132
  sequenceNodePath: firstEffectKeyframe.sequenceNodePath.nodePath,
129
133
  effectIndex: firstEffectKeyframe.effectIndex,
130
134
  videoConfigValues: firstEffectKeyframe.sequenceNodePath.videoConfigValues,
131
- updates: keyframeGroup.map((keyframe) => ({
132
- key: keyframe.key,
133
- operation: {
134
- type: 'remove',
135
- frame: keyframe.frame,
136
- },
137
- })),
135
+ updates: keyframeGroup.map((keyframe) => {
136
+ var _a;
137
+ return ({
138
+ key: keyframe.key,
139
+ operation: {
140
+ type: 'remove',
141
+ frame: keyframe.frame,
142
+ valueWhenLastKeyframeDeleted: (_a = keyframe.valueWhenLastKeyframeDeleted) !== null && _a !== void 0 ? _a : null,
143
+ },
144
+ });
145
+ }),
138
146
  });
139
147
  output = result.output;
140
148
  firstLogLine = Math.min(firstLogLine, result.logLine);
@@ -256,7 +256,8 @@ const downloadRemoteAssetHandler = async ({ input, publicDir, request }) => {
256
256
  type: 'asset',
257
257
  assetType: fileType.type === 'gif'
258
258
  ? 'gif'
259
- : fileType.type === 'apng'
259
+ : fileType.type === 'apng' ||
260
+ (fileType.type === 'webp' && fileType.animated)
260
261
  ? 'animated-image'
261
262
  : 'image',
262
263
  src: assetPath,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
4
4
  },
5
5
  "name": "@remotion/studio-server",
6
- "version": "4.0.493",
6
+ "version": "4.0.494",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -27,11 +27,11 @@
27
27
  "@babel/parser": "7.24.1",
28
28
  "semver": "7.5.3",
29
29
  "prettier": "3.8.1",
30
- "remotion": "4.0.493",
30
+ "remotion": "4.0.494",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.493",
33
- "@remotion/renderer": "4.0.493",
34
- "@remotion/studio-shared": "4.0.493",
32
+ "@remotion/bundler": "4.0.494",
33
+ "@remotion/renderer": "4.0.494",
34
+ "@remotion/studio-shared": "4.0.494",
35
35
  "memfs": "3.4.3",
36
36
  "open": "8.4.2"
37
37
  },
@@ -39,7 +39,7 @@
39
39
  "ast-types": "0.16.1",
40
40
  "react": "19.2.3",
41
41
  "@types/semver": "7.5.3",
42
- "@remotion/eslint-config-internal": "4.0.493",
42
+ "@remotion/eslint-config-internal": "4.0.494",
43
43
  "eslint": "9.19.0",
44
44
  "@types/node": "20.12.14",
45
45
  "@typescript/native-preview": "7.0.0-dev.20260217.1"