@remotion/studio-server 4.0.539 → 4.0.541

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/codemods/get-node-path-remappings.d.ts +5 -2
  2. package/dist/codemods/get-node-path-remappings.js +7 -1
  3. package/dist/file-watcher.d.ts +7 -1
  4. package/dist/file-watcher.js +33 -5
  5. package/dist/index.d.ts +6 -2
  6. package/dist/index.js +4 -0
  7. package/dist/preview-server/api-routes.js +4 -0
  8. package/dist/preview-server/commit-node-codemod.d.ts +27 -0
  9. package/dist/preview-server/commit-node-codemod.js +68 -0
  10. package/dist/preview-server/hot-middleware/index.js +11 -7
  11. package/dist/preview-server/live-events.js +8 -1
  12. package/dist/preview-server/prerendered-scene.d.ts +25 -0
  13. package/dist/preview-server/prerendered-scene.js +86 -0
  14. package/dist/preview-server/resolve-compiled-sequence-paths.d.ts +12 -0
  15. package/dist/preview-server/resolve-compiled-sequence-paths.js +155 -0
  16. package/dist/preview-server/routes/add-effect-keyframe.js +1 -1
  17. package/dist/preview-server/routes/add-keyframes.js +17 -9
  18. package/dist/preview-server/routes/add-render.js +28 -2
  19. package/dist/preview-server/routes/add-sequence-keyframe.js +1 -1
  20. package/dist/preview-server/routes/can-update-sequence-props.js +17 -4
  21. package/dist/preview-server/routes/delete-keyframes.d.ts +2 -2
  22. package/dist/preview-server/routes/delete-keyframes.js +36 -4
  23. package/dist/preview-server/routes/delete-nodes.js +1 -1
  24. package/dist/preview-server/routes/duplicate-nodes.js +3 -1
  25. package/dist/preview-server/routes/get-keyframe-mutation-results.d.ts +7 -0
  26. package/dist/preview-server/routes/get-keyframe-mutation-results.js +24 -0
  27. package/dist/preview-server/routes/invalidate-bundle.js +1 -1
  28. package/dist/preview-server/routes/move-keyframes.d.ts +2 -2
  29. package/dist/preview-server/routes/move-keyframes.js +36 -4
  30. package/dist/preview-server/routes/precompose-jsx-nodes.js +14 -10
  31. package/dist/preview-server/routes/prerendered-scene-info.d.ts +3 -0
  32. package/dist/preview-server/routes/prerendered-scene-info.js +31 -0
  33. package/dist/preview-server/routes/reorder-sequence.js +1 -1
  34. package/dist/preview-server/routes/replace-video-source.js +25 -78
  35. package/dist/preview-server/routes/restore-prerendered-scene.d.ts +3 -0
  36. package/dist/preview-server/routes/restore-prerendered-scene.js +38 -0
  37. package/dist/preview-server/routes/save-effect-props.js +1 -1
  38. package/dist/preview-server/routes/save-sequence-props.js +3 -1
  39. package/dist/preview-server/routes/split-sequences.js +10 -2
  40. package/dist/preview-server/routes/split-video-from-audio.js +1 -1
  41. package/dist/preview-server/routes/subscribe-to-sequence-props.js +50 -15
  42. package/dist/preview-server/routes/unwrap-node.js +1 -1
  43. package/dist/preview-server/routes/update-effect-keyframe-settings.js +1 -1
  44. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +1 -1
  45. package/dist/preview-server/routes/wrap-node.js +1 -1
  46. package/dist/preview-server/sequence-node-path-mutation-build.d.ts +2 -0
  47. package/dist/preview-server/sequence-node-path-mutation-build.js +221 -0
  48. package/dist/preview-server/sequence-node-path-mutation.d.ts +2 -1
  49. package/dist/preview-server/sequence-node-path-mutation.js +14 -2
  50. package/dist/preview-server/sequence-props-watchers.d.ts +2 -1
  51. package/dist/preview-server/sequence-props-watchers.js +11 -4
  52. package/dist/preview-server/serve-static.js +3 -0
  53. package/dist/preview-server/undo-stack.d.ts +1 -1
  54. package/dist/preview-server/undo-stack.js +14 -2
  55. package/dist/preview-server/watch-ignore-next-change.d.ts +1 -1
  56. package/dist/preview-server/watch-ignore-next-change.js +3 -3
  57. package/dist/remotion-skill-names.d.ts +1 -1
  58. package/dist/remotion-skill-names.js +1 -0
  59. package/dist/routes.js +91 -28
  60. package/package.json +10 -10
  61. package/dist/canvas-capture/generate-canvas-capture-composition.d.ts +0 -14
  62. package/dist/canvas-capture/generate-canvas-capture-composition.js +0 -239
  63. package/dist/codemods/add-effect.d.ts +0 -1
  64. package/dist/codemods/add-effect.js +0 -8
  65. package/dist/codemods/apply-codemod-to-file.d.ts +0 -7
  66. package/dist/codemods/apply-codemod-to-file.js +0 -171
  67. package/dist/codemods/apply-visual-control.d.ts +0 -8
  68. package/dist/codemods/apply-visual-control.js +0 -89
  69. package/dist/codemods/delete-effect.d.ts +0 -1
  70. package/dist/codemods/delete-effect.js +0 -6
  71. package/dist/codemods/delete-jsx-node.d.ts +0 -22
  72. package/dist/codemods/delete-jsx-node.js +0 -17
  73. package/dist/codemods/delete-jsx-nodes.d.ts +0 -13
  74. package/dist/codemods/delete-jsx-nodes.js +0 -10
  75. package/dist/codemods/duplicate-composition.d.ts +0 -2
  76. package/dist/codemods/duplicate-composition.js +0 -64
  77. package/dist/codemods/duplicate-effect.d.ts +0 -1
  78. package/dist/codemods/duplicate-effect.js +0 -6
  79. package/dist/codemods/duplicate-jsx-node.d.ts +0 -25
  80. package/dist/codemods/duplicate-jsx-node.js +0 -26
  81. package/dist/codemods/format-file-content.d.ts +0 -7
  82. package/dist/codemods/format-file-content.js +0 -80
  83. package/dist/codemods/format-inline-content.d.ts +0 -18
  84. package/dist/codemods/format-inline-content.js +0 -78
  85. package/dist/codemods/insert-video-layers.d.ts +0 -11
  86. package/dist/codemods/insert-video-layers.js +0 -5
  87. package/dist/codemods/recast-mods.d.ts +0 -13
  88. package/dist/codemods/recast-mods.js +0 -902
  89. package/dist/codemods/reorder-effect.d.ts +0 -1
  90. package/dist/codemods/reorder-effect.js +0 -5
  91. package/dist/codemods/reorder-sequence.d.ts +0 -1
  92. package/dist/codemods/reorder-sequence.js +0 -5
  93. package/dist/codemods/simple-diff.d.ts +0 -5
  94. package/dist/codemods/simple-diff.js +0 -39
  95. package/dist/codemods/split-jsx-sequence.d.ts +0 -27
  96. package/dist/codemods/split-jsx-sequence.js +0 -19
  97. package/dist/codemods/split-video-from-audio.d.ts +0 -1
  98. package/dist/codemods/split-video-from-audio.js +0 -5
  99. package/dist/codemods/update-default-props.d.ts +0 -1
  100. package/dist/codemods/update-default-props.js +0 -6
  101. package/dist/codemods/update-inline-caption-patches.d.ts +0 -1
  102. package/dist/codemods/update-inline-caption-patches.js +0 -5
  103. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +0 -1
  104. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +0 -7
  105. package/dist/open-browser-shortcut.d.ts +0 -9
  106. package/dist/open-browser-shortcut.js +0 -121
  107. package/dist/preview-server/hot-middleware/types.d.ts +0 -2
  108. package/dist/preview-server/hot-middleware/types.js +0 -2
  109. package/dist/preview-server/routes/apply-codemod.d.ts +0 -4
  110. package/dist/preview-server/routes/apply-codemod.js +0 -272
  111. package/dist/preview-server/routes/delete-jsx-node.d.ts +0 -3
  112. package/dist/preview-server/routes/delete-jsx-node.js +0 -126
  113. package/dist/preview-server/routes/delete-jsx-nodes.d.ts +0 -3
  114. package/dist/preview-server/routes/delete-jsx-nodes.js +0 -137
  115. package/dist/preview-server/routes/duplicate-jsx-node.d.ts +0 -3
  116. package/dist/preview-server/routes/duplicate-jsx-node.js +0 -118
  117. package/dist/preview-server/routes/insert-jsx-element.d.ts +0 -3
  118. package/dist/preview-server/routes/insert-jsx-element.js +0 -231
  119. package/dist/preview-server/routes/insert-video-layers.d.ts +0 -3
  120. package/dist/preview-server/routes/insert-video-layers.js +0 -68
  121. package/dist/preview-server/routes/split-jsx-sequence.d.ts +0 -3
  122. package/dist/preview-server/routes/split-jsx-sequence.js +0 -117
  123. package/dist/preview-server/routes/update-public-license.d.ts +0 -11
  124. package/dist/preview-server/routes/update-public-license.js +0 -97
  125. package/dist/preview-server/routes/wrap-jsx-node.d.ts +0 -3
  126. package/dist/preview-server/routes/wrap-jsx-node.js +0 -97
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveCompiledSequencePaths = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const codemods_1 = require("@remotion/codemods");
6
+ const read_source_file_1 = require("../helpers/read-source-file");
7
+ const resolve_file_inside_project_1 = require("../helpers/resolve-file-inside-project");
8
+ const undo_stack_1 = require("./undo-stack");
9
+ const resolveCompiledSequencePaths = ({ fileName, remotionRoot, fileContentsCache, targets, }) => {
10
+ var _a;
11
+ const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
12
+ remotionRoot,
13
+ fileName,
14
+ action: 'read',
15
+ });
16
+ const current = (0, read_source_file_1.readSourceFile)({ absolutePath, fileContentsCache });
17
+ const results = new Map();
18
+ const hashes = new Map();
19
+ const snapshots = new Map();
20
+ const inspect = (contents) => {
21
+ const cached = snapshots.get(contents);
22
+ if (cached !== undefined)
23
+ return cached;
24
+ try {
25
+ const nodes = (0, codemods_1.getNodes)({
26
+ project: { rootDir: remotionRoot, files: { [absolutePath]: contents } },
27
+ filePath: absolutePath,
28
+ });
29
+ const locations = new Map();
30
+ for (const { nodePath, location } of nodes) {
31
+ if (!location)
32
+ continue;
33
+ const key = `${location.line}:${location.column}`;
34
+ locations.set(key, locations.has(key) ? null : nodePath);
35
+ }
36
+ const snapshot = {
37
+ locations,
38
+ structure: JSON.stringify(nodes.map((n) => [n.nodePath, n.tagName, n.componentIdentity])),
39
+ };
40
+ snapshots.set(contents, snapshot);
41
+ return snapshot;
42
+ }
43
+ catch (_a) {
44
+ snapshots.set(contents, null);
45
+ return null;
46
+ }
47
+ };
48
+ const matchingTargets = new Map();
49
+ for (const target of targets) {
50
+ const group = (_a = matchingTargets.get(target.hash)) !== null && _a !== void 0 ? _a : [];
51
+ group.push(target);
52
+ matchingTargets.set(target.hash, group);
53
+ }
54
+ const acceptSnapshot = (contents, towardCurrent) => {
55
+ var _a;
56
+ var _b;
57
+ let hash = hashes.get(contents);
58
+ if (!hash) {
59
+ hash = (0, node_crypto_1.createHash)('sha256').update(contents).digest('hex');
60
+ hashes.set(contents, hash);
61
+ }
62
+ const group = matchingTargets.get(hash);
63
+ if (!group)
64
+ return;
65
+ const locations = (_a = inspect(contents)) === null || _a === void 0 ? void 0 : _a.locations;
66
+ const maps = towardCurrent.map((step) => {
67
+ if (step.remappings === null) {
68
+ // Props edits preserve JSX order, but pasted expressions can insert
69
+ // hooks. Without an explicit mapping every JSX path must still match.
70
+ const before = inspect(step.from);
71
+ const after = inspect(step.to);
72
+ return before !== null && before.structure === (after === null || after === void 0 ? void 0 : after.structure)
73
+ ? new Map()
74
+ : null;
75
+ }
76
+ const paths = new Map();
77
+ const destinations = new Set();
78
+ for (const { oldNodePath, newNodePath } of step.remappings) {
79
+ const from = step.reverse ? newNodePath : oldNodePath;
80
+ const to = step.reverse ? oldNodePath : newNodePath;
81
+ if (to !== null) {
82
+ const destination = JSON.stringify(to);
83
+ if (destinations.has(destination))
84
+ return null;
85
+ destinations.add(destination);
86
+ }
87
+ if (from === null)
88
+ continue;
89
+ const key = JSON.stringify(from);
90
+ if (paths.has(key))
91
+ return null;
92
+ paths.set(key, to);
93
+ }
94
+ // If a different node took a path, its former occupant cannot
95
+ // have survived there, even if the remapping omitted that occupant.
96
+ for (const key of destinations) {
97
+ if (!paths.has(key))
98
+ paths.set(key, null);
99
+ }
100
+ return paths;
101
+ });
102
+ for (const target of group) {
103
+ let nodePath = (_b = locations === null || locations === void 0 ? void 0 : locations.get(`${target.line}:${target.column}`)) !== null && _b !== void 0 ? _b : null;
104
+ for (let i = maps.length - 1; nodePath !== null && i >= 0; i--) {
105
+ const map = maps[i];
106
+ if (map === null) {
107
+ nodePath = null;
108
+ break;
109
+ }
110
+ const moved = map.get(JSON.stringify(nodePath));
111
+ if (moved !== undefined)
112
+ nodePath = moved;
113
+ }
114
+ // An identical source can occur on both sides of Undo. If those
115
+ // histories disagree, that hash cannot identify the live element.
116
+ const previous = results.get(target.index);
117
+ results.set(target.index, previous === undefined ||
118
+ JSON.stringify(previous) === JSON.stringify(nodePath)
119
+ ? nodePath
120
+ : null);
121
+ }
122
+ };
123
+ acceptSnapshot(current, []);
124
+ for (const [entries, reverse] of [
125
+ [(0, undo_stack_1.getUndoStack)(), false],
126
+ [(0, undo_stack_1.getRedoStack)(), true],
127
+ ]) {
128
+ let contents = current;
129
+ const changes = [];
130
+ for (let i = entries.length - 1; i >= 0; i--) {
131
+ const entry = entries[i];
132
+ const snapshot = entry.snapshots.find((s) => s.filePath === absolutePath);
133
+ if (!snapshot)
134
+ continue;
135
+ const from = reverse ? snapshot.newContents : snapshot.oldContents;
136
+ const to = reverse ? snapshot.oldContents : snapshot.newContents;
137
+ if (from === null ||
138
+ to !== contents ||
139
+ (snapshot.nodePathRemappings === null &&
140
+ entry.entryType !== 'sequence-props' &&
141
+ entry.entryType !== 'effect-props'))
142
+ break;
143
+ changes.push({
144
+ from,
145
+ to,
146
+ reverse,
147
+ remappings: snapshot.nodePathRemappings,
148
+ });
149
+ acceptSnapshot(from, changes);
150
+ contents = from;
151
+ }
152
+ }
153
+ return results;
154
+ };
155
+ exports.resolveCompiledSequencePaths = resolveCompiledSequencePaths;
@@ -48,7 +48,7 @@ const addEffectKeyframeHandler = ({ input: { fileName, sequenceNodePath, effectI
48
48
  (0, undo_stack_1.pushToUndoStack)({
49
49
  filePath: absolutePath,
50
50
  oldContents: fileContents,
51
- newContents: null,
51
+ newContents: output,
52
52
  logLevel,
53
53
  remotionRoot,
54
54
  logLine,
@@ -4,7 +4,6 @@ exports.addKeyframesHandler = exports.addKeyframes = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const renderer_1 = require("@remotion/renderer");
6
6
  const get_node_path_remappings_1 = require("../../codemods/get-node-path-remappings");
7
- const parse_ast_1 = require("../../codemods/parse-ast");
8
7
  const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
9
8
  const file_watcher_1 = require("../../file-watcher");
10
9
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
@@ -89,7 +88,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
89
88
  const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
90
89
  let output = fileContents;
91
90
  let firstLogLine = Number.POSITIVE_INFINITY;
92
- const originalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(fileContents));
91
+ const originalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)(fileContents);
93
92
  // Keyframe codemods may wrap a concise arrow in a return statement.
94
93
  // JSX nodes remain in order, but their node paths can all change.
95
94
  const currentPathFor = (originalPath) => {
@@ -97,7 +96,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
97
96
  if (index === -1) {
98
97
  throw new Error('Could not find the original JSX node for keyframing');
99
98
  }
100
- const currentNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(output));
99
+ const currentNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)(output);
101
100
  if (currentNodes.length !== originalNodes.length) {
102
101
  throw new Error('Could not remap JSX nodes after keyframing');
103
102
  }
@@ -169,7 +168,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
169
168
  });
170
169
  }
171
170
  }
172
- const finalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(output));
171
+ const finalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)(output);
173
172
  if (finalNodes.length !== originalNodes.length) {
174
173
  throw new Error('Could not remap JSX nodes after keyframing');
175
174
  }
@@ -178,11 +177,20 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
178
177
  oldContents: fileContents,
179
178
  newContents: output,
180
179
  logLine: Number.isFinite(firstLogLine) ? firstLogLine : 1,
181
- nodePathRemappings: originalNodes.flatMap(({ nodePath }, index) => {
182
- const newNodePath = finalNodes[index].nodePath;
183
- return JSON.stringify(nodePath) === JSON.stringify(newNodePath)
180
+ nodePathRemappings: originalNodes.flatMap(({ location, nodePath }, index) => {
181
+ var _a, _b;
182
+ const next = finalNodes[index];
183
+ return (location === null || location === void 0 ? void 0 : location.line) === ((_a = next.location) === null || _a === void 0 ? void 0 : _a.line) &&
184
+ (location === null || location === void 0 ? void 0 : location.column) === ((_b = next.location) === null || _b === void 0 ? void 0 : _b.column) &&
185
+ JSON.stringify(nodePath) === JSON.stringify(next.nodePath)
184
186
  ? []
185
- : [{ oldNodePath: nodePath, newNodePath }];
187
+ : [
188
+ {
189
+ oldNodePath: nodePath,
190
+ newNodePath: next.nodePath,
191
+ sourceLocations: { before: location, after: next.location },
192
+ },
193
+ ];
186
194
  }),
187
195
  });
188
196
  }
@@ -231,7 +239,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
231
239
  });
232
240
  }
233
241
  const nodePathMutation = filesWithRemappings.length
234
- ? (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(filesWithRemappings, null)
242
+ ? (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(filesWithRemappings, null, true)
235
243
  : null;
236
244
  for (const log of sequenceLogs) {
237
245
  (0, log_update_1.logUpdate)({
@@ -1,10 +1,31 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.handleAddRender = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
4
8
  const renderer_1 = require("@remotion/renderer");
5
- const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDirectory, methods: { addJob }, }) => {
9
+ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDirectory, publicDir, methods: { addJob }, }) => {
6
10
  const id = String(Math.random()).replace('0.', '');
7
11
  if (input.type === 'video') {
12
+ let { outName } = input;
13
+ let prerender = null;
14
+ if (input.prerenderTarget !== null) {
15
+ const absoluteOutName = node_path_1.default.resolve(publicDir, input.outName);
16
+ const src = node_path_1.default.relative(publicDir, absoluteOutName);
17
+ if (src.startsWith('..') || node_path_1.default.isAbsolute(src)) {
18
+ throw new Error('Pre-rendered videos must be saved in the public folder');
19
+ }
20
+ outName = node_path_1.default
21
+ .relative(remotionRoot, absoluteOutName)
22
+ .split(node_path_1.default.sep)
23
+ .join('/');
24
+ prerender = {
25
+ ...input.prerenderTarget,
26
+ src: src.split(node_path_1.default.sep).join('/'),
27
+ };
28
+ }
8
29
  addJob({
9
30
  entryPoint,
10
31
  remotionRoot,
@@ -18,7 +39,7 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
18
39
  status: 'idle',
19
40
  id,
20
41
  imageFormat: input.imageFormat,
21
- outName: input.outName,
42
+ outName,
22
43
  jpegQuality: input.jpegQuality,
23
44
  scale: input.scale,
24
45
  startedAt: Date.now(),
@@ -58,8 +79,10 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
58
79
  chromeMode: input.chromeMode,
59
80
  offthreadVideoThreads: input.offthreadVideoThreads,
60
81
  mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
82
+ preferredEffectBackend: input.preferredEffectBackend,
61
83
  sampleRate: input.sampleRate,
62
84
  licenseKey: input.licenseKey,
85
+ prerender,
63
86
  },
64
87
  logLevel,
65
88
  });
@@ -98,6 +121,8 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
98
121
  chromeMode: input.chromeMode,
99
122
  offthreadVideoThreads: input.offthreadVideoThreads,
100
123
  mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
124
+ preferredEffectBackend: input.preferredEffectBackend,
125
+ licenseKey: input.licenseKey,
101
126
  },
102
127
  logLevel,
103
128
  });
@@ -132,6 +157,7 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
132
157
  chromeMode: input.chromeMode,
133
158
  offthreadVideoThreads: input.offthreadVideoThreads,
134
159
  mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
160
+ preferredEffectBackend: input.preferredEffectBackend,
135
161
  licenseKey: input.licenseKey,
136
162
  },
137
163
  entryPoint,
@@ -44,7 +44,7 @@ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, v
44
44
  (0, undo_stack_1.pushToUndoStack)({
45
45
  filePath: absolutePath,
46
46
  oldContents: fileContents,
47
- newContents: null,
47
+ newContents: output,
48
48
  logLevel,
49
49
  remotionRoot,
50
50
  logLine,
@@ -973,14 +973,27 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
973
973
  exports.resolveSequencePropsNodePathsFromFilename = resolveSequencePropsNodePathsFromFilename;
974
974
  const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, }) => {
975
975
  try {
976
- return (0, codemods_1.getNodeProps)({
977
- project: { rootDir: '/', files: { 'source.tsx': fileContents } },
978
- node: { filePath: 'source.tsx', nodePath },
976
+ const result = codemods_1.CodemodsInternals.computeSequencePropsStatusFromContent({
977
+ fileContents,
978
+ includeSourceLocation: true,
979
+ nodePath,
979
980
  componentIdentity,
980
981
  keys,
981
982
  assetKeys,
982
- effectKeys: effects,
983
+ effects,
983
984
  });
985
+ const translate = result.props['style.translate'];
986
+ if (((translate === null || translate === void 0 ? void 0 : translate.status) === 'static' &&
987
+ typeof translate.codeValue === 'string' &&
988
+ translate.codeValue.includes('%')) ||
989
+ ((translate === null || translate === void 0 ? void 0 : translate.status) === 'keyframed' &&
990
+ translate.keyframes.some((keyframe) => typeof keyframe.value === 'string' && keyframe.value.includes('%')))) {
991
+ return {
992
+ ...result,
993
+ props: { ...result.props, 'style.translate': { status: 'computed' } },
994
+ };
995
+ }
996
+ return result;
984
997
  }
985
998
  catch (error) {
986
999
  if (error instanceof codemods_1.CodemodsInternals.JsxElementIdentityMismatchError) {
@@ -1,5 +1,5 @@
1
1
  import type { LogLevel } from '@remotion/renderer';
2
- import type { DeleteEffectKeyframe, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe } from '@remotion/studio-shared';
2
+ import type { DeleteEffectKeyframe, DeleteKeyframesRequest, DeleteKeyframesResponse, KeyframeMutationResult, DeleteSequenceKeyframe } from '@remotion/studio-shared';
3
3
  import type { ApiHandler } from '../api-types';
4
4
  export declare const deleteKeyframes: ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }: {
5
5
  sequenceKeyframes: DeleteSequenceKeyframe[];
@@ -7,5 +7,5 @@ export declare const deleteKeyframes: ({ sequenceKeyframes, effectKeyframes, cli
7
7
  clientId: string;
8
8
  remotionRoot: string;
9
9
  logLevel: LogLevel;
10
- }) => Promise<void>;
10
+ }) => Promise<KeyframeMutationResult[]>;
11
11
  export declare const deleteKeyframesHandler: ApiHandler<DeleteKeyframesRequest, DeleteKeyframesResponse>;
@@ -8,6 +8,7 @@ const file_watcher_1 = require("../../file-watcher");
8
8
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
9
9
  const undo_stack_1 = require("../undo-stack");
10
10
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
11
+ const get_keyframe_mutation_results_1 = require("./get-keyframe-mutation-results");
11
12
  const log_effect_update_1 = require("./log-updates/log-effect-update");
12
13
  const log_update_1 = require("./log-updates/log-update");
13
14
  const source_file_write_queue_1 = require("./source-file-write-queue");
@@ -35,7 +36,7 @@ const getBatchDescription = ({ totalKeyframes, firstKeyframe, }) => {
35
36
  };
36
37
  };
37
38
  const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }) => {
38
- var _a, _b;
39
+ var _a, _b, _c;
39
40
  const totalKeyframes = sequenceKeyframes.length + effectKeyframes.length;
40
41
  if (totalKeyframes === 0) {
41
42
  throw new Error('No keyframes were specified for deletion');
@@ -67,6 +68,8 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
67
68
  group.effectKeyframes.push({ ...keyframe, fileRelativeToRoot });
68
69
  fileGroups.set(absolutePath, group);
69
70
  }
71
+ const results = [];
72
+ const resultsByFile = new Map();
70
73
  const snapshots = [];
71
74
  const sequenceLogs = [];
72
75
  const effectLogs = [];
@@ -74,6 +77,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
74
77
  const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
75
78
  let output = fileContents;
76
79
  let firstLogLine = Number.POSITIVE_INFINITY;
80
+ const targets = [];
77
81
  for (const keyframeGroup of groupBy(group.sequenceKeyframes, (keyframe) => JSON.stringify(keyframe.nodePath.nodePath))) {
78
82
  const [firstSequenceKeyframe] = keyframeGroup;
79
83
  if (!firstSequenceKeyframe) {
@@ -97,6 +101,15 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
97
101
  }),
98
102
  });
99
103
  output = result.output;
104
+ targets.push({
105
+ nodePath: {
106
+ ...firstSequenceKeyframe.nodePath,
107
+ absolutePath,
108
+ nodePath: result.updatedNode.nodePath,
109
+ },
110
+ effectIndex: null,
111
+ keys: [...new Set(keyframeGroup.map((keyframe) => keyframe.key))],
112
+ });
100
113
  firstLogLine = Math.min(firstLogLine, result.logLine);
101
114
  for (const [keyframeIndex, keyframe] of keyframeGroup.entries()) {
102
115
  sequenceLogs.push({
@@ -133,6 +146,15 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
133
146
  }),
134
147
  });
135
148
  output = result.output;
149
+ targets.push({
150
+ nodePath: {
151
+ ...firstEffectKeyframe.sequenceNodePath,
152
+ absolutePath,
153
+ nodePath: result.updatedEffect.nodePath,
154
+ },
155
+ effectIndex: firstEffectKeyframe.effectIndex,
156
+ keys: [...new Set(keyframeGroup.map((keyframe) => keyframe.key))],
157
+ });
136
158
  firstLogLine = Math.min(firstLogLine, result.logLine);
137
159
  for (const [keyframeIndex, keyframe] of keyframeGroup.entries()) {
138
160
  effectLogs.push({
@@ -146,6 +168,12 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
146
168
  });
147
169
  }
148
170
  }
171
+ const fileResults = (0, get_keyframe_mutation_results_1.getKeyframeMutationResults)({
172
+ fileContents: output,
173
+ targets,
174
+ });
175
+ results.push(...fileResults);
176
+ resultsByFile.set(absolutePath, fileResults);
149
177
  snapshots.push({
150
178
  filePath: absolutePath,
151
179
  oldContents: fileContents,
@@ -176,12 +204,15 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
176
204
  for (const snapshot of snapshots) {
177
205
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
178
206
  (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(snapshot.filePath);
179
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
207
+ const sourceVersion = (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
180
208
  file: snapshot.filePath,
181
209
  content: snapshot.newContents,
182
210
  originatorClientId: clientId,
183
211
  metadata: null,
184
212
  });
213
+ for (const result of (_c = resultsByFile.get(snapshot.filePath)) !== null && _c !== void 0 ? _c : []) {
214
+ result.sourceVersion = sourceVersion;
215
+ }
185
216
  }
186
217
  for (const log of sequenceLogs) {
187
218
  (0, log_update_1.logUpdate)({
@@ -213,17 +244,18 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
213
244
  });
214
245
  }
215
246
  (0, undo_stack_1.printUndoHint)(logLevel);
247
+ return results;
216
248
  };
217
249
  exports.deleteKeyframes = deleteKeyframes;
218
250
  const deleteKeyframesHandler = ({ input: { sequenceKeyframes, effectKeyframes, clientId }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
219
251
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-keyframes] Received request to delete ${sequenceKeyframes.length + effectKeyframes.length} keyframe(s)`);
220
- await (0, exports.deleteKeyframes)({
252
+ const results = await (0, exports.deleteKeyframes)({
221
253
  sequenceKeyframes,
222
254
  effectKeyframes,
223
255
  clientId,
224
256
  remotionRoot,
225
257
  logLevel,
226
258
  });
227
- return { success: true };
259
+ return { success: true, results };
228
260
  });
229
261
  exports.deleteKeyframesHandler = deleteKeyframesHandler;
@@ -87,7 +87,7 @@ const deleteNodesHandler = ({ input: { nodes }, remotionRoot, logLevel }) => {
87
87
  (0, undo_stack_1.pushToUndoStack)({
88
88
  filePath: update.absolutePath,
89
89
  oldContents: update.fileContents,
90
- newContents: null,
90
+ newContents: update.output,
91
91
  logLevel,
92
92
  remotionRoot,
93
93
  logLine: update.logLine,
@@ -58,6 +58,7 @@ const duplicateNodesHandler = ({ input: { nodes }, remotionRoot, logLevel }) =>
58
58
  logLine: Math.min(...logLines),
59
59
  nodeLabels,
60
60
  nodePathRemappings,
61
+ duplicatedNodes: result.duplicatedNodes.map(({ filePath, nodePath }) => ({ absolutePath: filePath, nodePath })),
61
62
  output,
62
63
  };
63
64
  }));
@@ -72,7 +73,7 @@ const duplicateNodesHandler = ({ input: { nodes }, remotionRoot, logLevel }) =>
72
73
  snapshots: updates.map((update) => ({
73
74
  filePath: update.absolutePath,
74
75
  oldContents: update.fileContents,
75
- newContents: null,
76
+ newContents: update.output,
76
77
  logLine: update.logLine,
77
78
  nodePathRemappings: update.nodePathRemappings,
78
79
  })),
@@ -109,6 +110,7 @@ const duplicateNodesHandler = ({ input: { nodes }, remotionRoot, logLevel }) =>
109
110
  return {
110
111
  success: true,
111
112
  nodePathMutation,
113
+ duplicatedNodes: updates.flatMap((update) => update.duplicatedNodes),
112
114
  };
113
115
  }
114
116
  catch (err) {
@@ -0,0 +1,7 @@
1
+ import type { KeyframeMutationResult } from '@remotion/studio-shared';
2
+ export declare const getKeyframeMutationResults: ({ fileContents, targets, }: {
3
+ fileContents: string;
4
+ targets: readonly (Pick<KeyframeMutationResult, 'nodePath' | 'effectIndex'> & {
5
+ keys: string[];
6
+ })[];
7
+ }) => KeyframeMutationResult[];
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getKeyframeMutationResults = void 0;
4
+ const codemods_1 = require("@remotion/codemods");
5
+ const getKeyframeMutationResults = ({ fileContents, targets, }) => {
6
+ return targets.map(({ nodePath, effectIndex, keys }) => {
7
+ const status = (0, codemods_1.getNodeProps)({
8
+ project: { rootDir: '/', files: { 'source.tsx': fileContents } },
9
+ node: { filePath: 'source.tsx', nodePath: nodePath.nodePath },
10
+ componentIdentity: null,
11
+ keys: effectIndex === null ? keys : [],
12
+ effectKeys: effectIndex === null
13
+ ? []
14
+ : Array.from({ length: effectIndex + 1 }, (_, index) => index === effectIndex ? keys : []),
15
+ });
16
+ if (effectIndex === null)
17
+ return { nodePath, effectIndex, props: status.props, sourceVersion: null };
18
+ const effect = status.effects[effectIndex];
19
+ if (!(effect === null || effect === void 0 ? void 0 : effect.canUpdate))
20
+ throw new Error('Could not read the updated effect keyframes');
21
+ return { nodePath, effectIndex, props: effect.props, sourceVersion: null };
22
+ });
23
+ };
24
+ exports.getKeyframeMutationResults = getKeyframeMutationResults;
@@ -5,7 +5,7 @@ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
5
5
  const source_file_write_queue_1 = require("./source-file-write-queue");
6
6
  const invalidateBundleHandler = () => {
7
7
  return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
8
- return { didInvalidate: await (0, watch_ignore_next_change_1.invalidatePreviouslySuppressedFiles)() };
8
+ return { didInvalidate: await (0, watch_ignore_next_change_1.invalidatePreviouslySuppressedFiles)(null) };
9
9
  });
10
10
  };
11
11
  exports.invalidateBundleHandler = invalidateBundleHandler;
@@ -1,8 +1,8 @@
1
1
  import type { LogLevel } from '@remotion/renderer';
2
- import type { MoveKeyframesRequest, MoveKeyframesResponse } from '@remotion/studio-shared';
2
+ import type { MoveKeyframesRequest, MoveKeyframesResponse, KeyframeMutationResult } from '@remotion/studio-shared';
3
3
  import type { ApiHandler } from '../api-types';
4
4
  export declare const moveKeyframes: ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }: MoveKeyframesRequest & {
5
5
  remotionRoot: string;
6
6
  logLevel: LogLevel;
7
- }) => Promise<void>;
7
+ }) => Promise<KeyframeMutationResult[]>;
8
8
  export declare const moveKeyframesHandler: ApiHandler<MoveKeyframesRequest, MoveKeyframesResponse>;