@remotion/studio-server 4.0.536 → 4.0.538

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 (98) hide show
  1. package/dist/ansi-diff.js +3 -19
  2. package/dist/better-opn/index.d.ts +4 -2
  3. package/dist/codemods/effect-param-expression.d.ts +2 -2
  4. package/dist/codemods/get-node-path-remappings.d.ts +1 -12
  5. package/dist/codemods/get-node-path-remappings.js +1 -51
  6. package/dist/codemods/paste-effects.d.ts +2 -15
  7. package/dist/codemods/update-effect-props/update-effect-props.d.ts +2 -2
  8. package/dist/codemods/update-keyframes/update-keyframes.d.ts +3 -3
  9. package/dist/codemods/update-nested-prop.d.ts +1 -1
  10. package/dist/detect-outdated-remotion-skills.d.ts +3 -3
  11. package/dist/figma/figma-to-svg.d.ts +1 -1
  12. package/dist/file-watcher.d.ts +1 -1
  13. package/dist/helpers/coding-agent-registry.d.ts +3 -3
  14. package/dist/helpers/css-shorthand-properties.d.ts +8 -7
  15. package/dist/helpers/custom-editor.d.ts +2 -2
  16. package/dist/helpers/editor-registry.d.ts +2 -2
  17. package/dist/helpers/get-ast-node-path.d.ts +2 -1
  18. package/dist/helpers/import-agnostic-node-path.js +22 -13
  19. package/dist/helpers/open-in-app.d.ts +3 -3
  20. package/dist/helpers/open-in-editor.d.ts +2 -2
  21. package/dist/helpers/package-manager-spawn-options.d.ts +1 -1
  22. package/dist/helpers/read-source-file.d.ts +4 -0
  23. package/dist/helpers/read-source-file.js +14 -0
  24. package/dist/helpers/recently-used-apps.d.ts +2 -2
  25. package/dist/helpers/resolve-composition-component.d.ts +2 -2
  26. package/dist/helpers/resolve-editor.d.ts +3 -3
  27. package/dist/helpers/terminal-artwork.d.ts +4 -4
  28. package/dist/helpers/video-config-values.d.ts +4 -0
  29. package/dist/helpers/video-config-values.js +11 -3
  30. package/dist/index.d.ts +39 -100
  31. package/dist/index.js +1 -1
  32. package/dist/maybe-open-browser.d.ts +2 -1
  33. package/dist/preview-server/api-routes.js +2 -0
  34. package/dist/preview-server/api-types.d.ts +1 -1
  35. package/dist/preview-server/default-props-watchers.d.ts +3 -2
  36. package/dist/preview-server/default-props-watchers.js +48 -77
  37. package/dist/preview-server/dev-middleware/index.d.ts +2 -1
  38. package/dist/preview-server/dev-middleware/middleware.d.ts +1 -1
  39. package/dist/preview-server/dev-middleware/middleware.js +14 -17
  40. package/dist/preview-server/element-install-state.d.ts +1 -1
  41. package/dist/preview-server/get-package-manager.d.ts +3 -2
  42. package/dist/preview-server/handler.d.ts +4 -4
  43. package/dist/preview-server/hmr-timing.d.ts +2 -1
  44. package/dist/preview-server/hot-middleware/index.d.ts +2 -1
  45. package/dist/preview-server/jsx-component-identity.d.ts +4 -3
  46. package/dist/preview-server/live-events.d.ts +3 -2
  47. package/dist/preview-server/public-folder.js +11 -2
  48. package/dist/preview-server/routes/add-keyframes.d.ts +2 -1
  49. package/dist/preview-server/routes/app-icon.d.ts +1 -1
  50. package/dist/preview-server/routes/apply-visual-control-change.js +1 -4
  51. package/dist/preview-server/routes/batch-update-keyframe-settings.d.ts +2 -1
  52. package/dist/preview-server/routes/can-update-default-props.d.ts +11 -4
  53. package/dist/preview-server/routes/can-update-default-props.js +43 -10
  54. package/dist/preview-server/routes/can-update-effect-props.d.ts +2 -6
  55. package/dist/preview-server/routes/can-update-sequence-props.d.ts +17 -13
  56. package/dist/preview-server/routes/can-update-sequence-props.js +21 -25
  57. package/dist/preview-server/routes/delete-keyframes.d.ts +4 -6
  58. package/dist/preview-server/routes/delete-keyframes.js +4 -66
  59. package/dist/preview-server/routes/element-install-plan.d.ts +3 -3
  60. package/dist/preview-server/routes/find-in-file.d.ts +2 -9
  61. package/dist/preview-server/routes/insert-element.js +1 -4
  62. package/dist/preview-server/routes/install-dependency.d.ts +2 -14
  63. package/dist/preview-server/routes/log-updates/log-effect-update.d.ts +2 -1
  64. package/dist/preview-server/routes/log-updates/log-update.d.ts +3 -2
  65. package/dist/preview-server/routes/move-keyframes.d.ts +2 -1
  66. package/dist/preview-server/routes/open-in-editor.d.ts +2 -2
  67. package/dist/preview-server/routes/remotion-skills-info.d.ts +1 -1
  68. package/dist/preview-server/routes/save-multiple-effect-props.js +25 -8
  69. package/dist/preview-server/routes/save-sequence-props.d.ts +2 -2
  70. package/dist/preview-server/routes/source-file-write-queue.d.ts +3 -2
  71. package/dist/preview-server/routes/subscribe-to-default-props.js +2 -1
  72. package/dist/preview-server/routes/subscribe-to-sequence-props.js +55 -34
  73. package/dist/preview-server/routes/unsubscribe-from-sequence-props.d.ts +2 -2
  74. package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +12 -10
  75. package/dist/preview-server/routes/unwrap-node.d.ts +3 -0
  76. package/dist/preview-server/routes/unwrap-node.js +98 -0
  77. package/dist/preview-server/routes/update-default-props.js +15 -15
  78. package/dist/preview-server/sequence-node-path-mutation.d.ts +2 -6
  79. package/dist/preview-server/sequence-props-watchers.d.ts +7 -5
  80. package/dist/preview-server/sequence-props-watchers.js +14 -4
  81. package/dist/preview-server/serve-static.d.ts +1 -1
  82. package/dist/preview-server/serve-static.js +18 -1
  83. package/dist/preview-server/start-server.d.ts +3 -3
  84. package/dist/preview-server/studio-protocol/handle-discovery.d.ts +1 -1
  85. package/dist/preview-server/studio-protocol/handle-element-library.d.ts +1 -1
  86. package/dist/preview-server/studio-protocol/handle-install.d.ts +1 -1
  87. package/dist/preview-server/studio-protocol/handle-license-key.d.ts +1 -1
  88. package/dist/preview-server/studio-protocol/origin-policy.d.ts +2 -2
  89. package/dist/preview-server/studio-protocol/protocol-response.d.ts +1 -1
  90. package/dist/preview-server/undo-stack.d.ts +4 -4
  91. package/dist/preview-server/undo-stack.js +9 -0
  92. package/dist/preview-server/update-available.d.ts +3 -2
  93. package/dist/remotion-skill-names.d.ts +1 -1
  94. package/dist/routes.d.ts +4 -4
  95. package/dist/server-ready.d.ts +2 -1
  96. package/dist/start-studio.d.ts +3 -3
  97. package/dist/studio-shortcuts.d.ts +3 -3
  98. package/package.json +10 -10
@@ -3,16 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteKeyframesHandler = exports.deleteKeyframes = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const renderer_1 = require("@remotion/renderer");
6
- const studio_shared_1 = require("@remotion/studio-shared");
7
- const parse_ast_1 = require("../../codemods/parse-ast");
8
6
  const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
9
7
  const file_watcher_1 = require("../../file-watcher");
10
8
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
11
- const video_config_values_1 = require("../../helpers/video-config-values");
12
9
  const undo_stack_1 = require("../undo-stack");
13
10
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
14
- const can_update_effect_props_1 = require("./can-update-effect-props");
15
- const can_update_sequence_props_1 = require("./can-update-sequence-props");
16
11
  const log_effect_update_1 = require("./log-updates/log-effect-update");
17
12
  const log_update_1 = require("./log-updates/log-update");
18
13
  const source_file_write_queue_1 = require("./source-file-write-queue");
@@ -46,42 +41,33 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
46
41
  throw new Error('No keyframes were specified for deletion');
47
42
  }
48
43
  const fileGroups = new Map();
49
- const resolvedSequenceKeyframes = [];
50
- const resolvedEffectKeyframes = [];
51
- for (const [index, keyframe] of sequenceKeyframes.entries()) {
44
+ for (const keyframe of sequenceKeyframes) {
52
45
  const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
53
46
  remotionRoot,
54
47
  fileName: keyframe.fileName,
55
48
  action: 'modify',
56
49
  });
57
50
  const group = (_a = fileGroups.get(absolutePath)) !== null && _a !== void 0 ? _a : {
58
- fileRelativeToRoot,
59
51
  sequenceKeyframes: [],
60
52
  effectKeyframes: [],
61
53
  };
62
- const resolved = { ...keyframe, index, absolutePath, fileRelativeToRoot };
63
- group.sequenceKeyframes.push(resolved);
64
- resolvedSequenceKeyframes.push(resolved);
54
+ group.sequenceKeyframes.push({ ...keyframe, fileRelativeToRoot });
65
55
  fileGroups.set(absolutePath, group);
66
56
  }
67
- for (const [index, keyframe] of effectKeyframes.entries()) {
57
+ for (const keyframe of effectKeyframes) {
68
58
  const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
69
59
  remotionRoot,
70
60
  fileName: keyframe.fileName,
71
61
  action: 'modify',
72
62
  });
73
63
  const group = (_b = fileGroups.get(absolutePath)) !== null && _b !== void 0 ? _b : {
74
- fileRelativeToRoot,
75
64
  sequenceKeyframes: [],
76
65
  effectKeyframes: [],
77
66
  };
78
- const resolved = { ...keyframe, index, absolutePath, fileRelativeToRoot };
79
- group.effectKeyframes.push(resolved);
80
- resolvedEffectKeyframes.push(resolved);
67
+ group.effectKeyframes.push({ ...keyframe, fileRelativeToRoot });
81
68
  fileGroups.set(absolutePath, group);
82
69
  }
83
70
  const snapshots = [];
84
- const outputByPath = new Map();
85
71
  const sequenceLogs = [];
86
72
  const effectLogs = [];
87
73
  for (const [absolutePath, group] of fileGroups) {
@@ -166,7 +152,6 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
166
152
  newContents: output,
167
153
  logLine: Number.isFinite(firstLogLine) ? firstLogLine : 1,
168
154
  });
169
- outputByPath.set(absolutePath, output);
170
155
  }
171
156
  const [firstKeyframe] = sequenceKeyframes.length > 0 ? sequenceKeyframes : effectKeyframes;
172
157
  if (!firstKeyframe) {
@@ -228,53 +213,6 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
228
213
  });
229
214
  }
230
215
  (0, undo_stack_1.printUndoHint)(logLevel);
231
- const sequenceResults = resolvedSequenceKeyframes.map((keyframe) => {
232
- const output = outputByPath.get(keyframe.absolutePath);
233
- if (!output) {
234
- throw new Error('Could not compute sequence keyframe deletion status');
235
- }
236
- const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
237
- fileContents: output,
238
- keys: (0, studio_shared_1.getAllSchemaKeys)(keyframe.schema),
239
- nodePath: keyframe.nodePath.nodePath,
240
- componentIdentity: null,
241
- effects: [],
242
- });
243
- return {
244
- fileName: keyframe.fileName,
245
- nodePath: keyframe.nodePath,
246
- props: status.props,
247
- };
248
- });
249
- const astByPath = new Map();
250
- const effectResults = resolvedEffectKeyframes.map((keyframe) => {
251
- var _a;
252
- const output = outputByPath.get(keyframe.absolutePath);
253
- if (!output) {
254
- throw new Error('Could not compute effect keyframe deletion status');
255
- }
256
- const ast = (_a = astByPath.get(keyframe.absolutePath)) !== null && _a !== void 0 ? _a : (0, parse_ast_1.parseAst)(output);
257
- astByPath.set(keyframe.absolutePath, ast);
258
- const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, keyframe.sequenceNodePath.nodePath);
259
- if (!jsx) {
260
- return {
261
- canUpdate: false,
262
- effectIndex: keyframe.effectIndex,
263
- reason: 'not-found',
264
- };
265
- }
266
- return (0, can_update_effect_props_1.computeEffectPropStatus)({
267
- ast,
268
- jsx,
269
- effectIndex: keyframe.effectIndex,
270
- keys: (0, studio_shared_1.getAllSchemaKeys)(keyframe.schema),
271
- videoConfigValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
272
- ast,
273
- videoConfigValues: keyframe.sequenceNodePath.videoConfigValues,
274
- }),
275
- });
276
- });
277
- return { sequenceResults, effectResults };
278
216
  };
279
217
  exports.deleteKeyframes = deleteKeyframes;
280
218
  const deleteKeyframesHandler = ({ input: { sequenceKeyframes, effectKeyframes, clientId }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
@@ -1,7 +1,7 @@
1
- import type { ElementInstallExpectedFileState, PrepareElementInstallRequest } from '@remotion/studio-shared';
1
+ import type { ElementInstallExpectedFileState, InsertElementRequest, PrepareElementInstallRequest } from '@remotion/studio-shared';
2
2
  export declare const getElementSourceHash: (source: string) => string;
3
- export declare const validateElementInstallPosition: (position: import("@remotion/studio-shared").InsertableCompositionElementPosition | null) => void;
4
- export declare const validateElementForInstallation: (element: import("@remotion/studio-shared").InstallableElement) => void;
3
+ export declare const validateElementInstallPosition: (position: InsertElementRequest['position']) => void;
4
+ export declare const validateElementForInstallation: (element: InsertElementRequest['element']) => void;
5
5
  export declare const makeRelativeElementImportPath: ({ fromFile, toFile, }: {
6
6
  fromFile: string;
7
7
  toFile: string;
@@ -1,12 +1,5 @@
1
+ import { CodemodsInternals } from '@remotion/codemods';
1
2
  import type { FindInFileRequest, FindInFileResponse } from '@remotion/studio-shared';
2
3
  import type { ApiHandler } from '../api-types';
3
- export declare const findSearchPosition: ({ contents, lineNumber, columnNumber, search, }: {
4
- contents: string;
5
- lineNumber: number;
6
- columnNumber: number;
7
- search: string;
8
- }) => {
9
- lineNumber: number;
10
- columnNumber: number;
11
- };
4
+ export declare const { findSearchPosition }: typeof CodemodsInternals;
12
5
  export declare const findInFileHandler: ApiHandler<FindInFileRequest, FindInFileResponse>;
@@ -79,10 +79,7 @@ const insertElementHandler = async ({ input: { compositionFile, compositionId, c
79
79
  const componentOwnsSequence = installationMode === 'component-owned-sequence';
80
80
  if (componentOwnsSequence &&
81
81
  element.initialProps !== null &&
82
- ['from', 'durationInFrames', 'name'].some((prop) => {
83
- var _a;
84
- return Object.hasOwn((_a = element.initialProps) !== null && _a !== void 0 ? _a : {}, prop);
85
- })) {
82
+ ['from', 'durationInFrames', 'name'].some((prop) => { var _a; return Object.hasOwn((_a = element.initialProps) !== null && _a !== void 0 ? _a : {}, prop); })) {
86
83
  throw new Error('Component-owned Element initial props must not override from, durationInFrames, or name');
87
84
  }
88
85
  if (componentOwnsSequence &&
@@ -1,18 +1,6 @@
1
1
  import { type InstallPackageRequest, type InstallPackageResponse, type PackageInstallSpec } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
2
3
  export declare const getPackageInstallSpec: (dependency: PackageInstallSpec) => string;
3
- export declare const handleInstallPackage: ({ logLevel, remotionRoot, input: { dependencies }, invalidateBundle, }: {
4
- input: InstallPackageRequest;
5
- entryPoint: string;
6
- remotionRoot: string;
7
- request: import("http").IncomingMessage;
8
- response: import("http").ServerResponse<import("http").IncomingMessage>;
9
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
10
- methods: import("../api-types").QueueMethods;
11
- publicDir: string;
12
- binariesDirectory: string | null;
13
- configFile: string | null;
14
- getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
15
- getDefaultEditor: () => import("@remotion/renderer").DefaultEditor | null;
16
- } & {
4
+ export declare const handleInstallPackage: ({ logLevel, remotionRoot, input: { dependencies }, invalidateBundle, }: Parameters<ApiHandler<InstallPackageRequest, InstallPackageResponse>>[0] & {
17
5
  readonly invalidateBundle: () => Promise<void>;
18
6
  }) => Promise<InstallPackageResponse>;
@@ -1,3 +1,4 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  import type { PropDelta } from './formatting';
2
3
  export declare const logEffectUpdate: ({ fileRelativeToRoot, line, effectName, propKey, oldValueString, newValueString, defaultValueString, formatted, logLevel, removedProps, addedProps, }: {
3
4
  fileRelativeToRoot: string;
@@ -8,7 +9,7 @@ export declare const logEffectUpdate: ({ fileRelativeToRoot, line, effectName, p
8
9
  newValueString: string;
9
10
  defaultValueString: string | null;
10
11
  formatted: boolean;
11
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
12
+ logLevel: LogLevel;
12
13
  removedProps: PropDelta[];
13
14
  addedProps: PropDelta[];
14
15
  }) => void;
@@ -1,5 +1,6 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  import type { PropDelta } from './formatting';
2
- export declare const warnAboutPrettierOnce: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => void;
3
+ export declare const warnAboutPrettierOnce: (logLevel: LogLevel) => void;
3
4
  export declare const normalizeQuotes: (str: string) => string;
4
5
  export declare const logUpdate: ({ fileRelativeToRoot, line, key, oldValueString, newValueString, defaultValueString, formatted, logLevel, removedProps, addedProps, }: {
5
6
  fileRelativeToRoot: string;
@@ -9,7 +10,7 @@ export declare const logUpdate: ({ fileRelativeToRoot, line, key, oldValueString
9
10
  newValueString: string;
10
11
  defaultValueString: string | null;
11
12
  formatted: boolean;
12
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
13
+ logLevel: LogLevel;
13
14
  removedProps: PropDelta[];
14
15
  addedProps: PropDelta[];
15
16
  }) => void;
@@ -1,7 +1,8 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  import type { MoveKeyframesRequest, MoveKeyframesResponse } from '@remotion/studio-shared';
2
3
  import type { ApiHandler } from '../api-types';
3
4
  export declare const moveKeyframes: ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }: MoveKeyframesRequest & {
4
5
  remotionRoot: string;
5
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
6
+ logLevel: LogLevel;
6
7
  }) => Promise<void>;
7
8
  export declare const moveKeyframesHandler: ApiHandler<MoveKeyframesRequest, MoveKeyframesResponse>;
@@ -1,8 +1,8 @@
1
- import type { DefaultEditor } from '@remotion/renderer';
1
+ import type { DefaultEditor, LogLevel } from '@remotion/renderer';
2
2
  import type { OpenInEditorRequest, OpenInEditorResponse } from '@remotion/studio-shared';
3
3
  import type { ApiHandler } from '../api-types';
4
4
  export declare const getEditorName: ({ getDefaultEditor, logLevel, }: {
5
5
  getDefaultEditor: () => DefaultEditor | null;
6
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
6
+ logLevel: LogLevel;
7
7
  }) => Promise<string | null>;
8
8
  export declare const openInEditorHandler: ApiHandler<OpenInEditorRequest, OpenInEditorResponse>;
@@ -2,7 +2,7 @@ import type { GetRemotionSkillsInfoRequest, GetRemotionSkillsInfoResponse, OpenR
2
2
  import type { ApiHandler } from '../api-types';
3
3
  export declare const getRemotionSkillsInfo: ({ remotionRoot, homeDirectory, }: {
4
4
  remotionRoot: string;
5
- homeDirectory?: string | undefined;
5
+ homeDirectory?: string;
6
6
  }) => GetRemotionSkillsInfoResponse;
7
7
  export declare const remotionSkillsInfoHandler: ApiHandler<GetRemotionSkillsInfoRequest, GetRemotionSkillsInfoResponse>;
8
8
  export declare const openRemotionSkillHandler: ApiHandler<OpenRemotionSkillRequest, void>;
@@ -141,6 +141,9 @@ const saveMultipleEffectPropsHandler = ({ input: { edits, clientId, undoLabel, r
141
141
  edit,
142
142
  ])).values(),
143
143
  ];
144
+ const statusAsts = new Map();
145
+ // Share binding analysis, but resolve each target's video configuration below.
146
+ const statusIdentifiers = new Map();
144
147
  const results = statusTargets.map((edit) => {
145
148
  const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
146
149
  remotionRoot,
@@ -151,24 +154,38 @@ const saveMultipleEffectPropsHandler = ({ input: { edits, clientId, undoLabel, r
151
154
  if (!output) {
152
155
  throw new Error('Could not compute effect prop edit status');
153
156
  }
154
- const ast = (0, parse_ast_1.parseAst)(output);
157
+ let ast = statusAsts.get(absolutePath);
158
+ if (!ast) {
159
+ ast = (0, parse_ast_1.parseAst)(output);
160
+ statusAsts.set(absolutePath, ast);
161
+ }
155
162
  const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, edit.sequenceNodePath.nodePath);
156
- const status = jsx
157
- ? (0, can_update_effect_props_1.computeEffectPropStatus)({
163
+ let status;
164
+ if (jsx) {
165
+ const keys = (0, studio_shared_1.getAllSchemaKeys)(edit.schema);
166
+ let identifiers = statusIdentifiers.get(absolutePath);
167
+ if (!identifiers) {
168
+ identifiers = (0, video_config_values_1.getVideoConfigIdentifiers)({ ast });
169
+ statusIdentifiers.set(absolutePath, identifiers);
170
+ }
171
+ status = (0, can_update_effect_props_1.computeEffectPropStatus)({
158
172
  ast,
159
173
  jsx,
160
174
  effectIndex: edit.effectIndex,
161
- keys: (0, studio_shared_1.getAllSchemaKeys)(edit.schema),
162
- videoConfigValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
163
- ast,
175
+ keys,
176
+ videoConfigValues: (0, video_config_values_1.resolveVideoConfigIdentifierValues)({
177
+ identifiers,
164
178
  videoConfigValues: edit.sequenceNodePath.videoConfigValues,
165
179
  }),
166
- })
167
- : {
180
+ });
181
+ }
182
+ else {
183
+ status = {
168
184
  canUpdate: false,
169
185
  effectIndex: edit.effectIndex,
170
186
  reason: 'not-found',
171
187
  };
188
+ }
172
189
  return {
173
190
  fileName: edit.fileName,
174
191
  sequenceNodePath: edit.sequenceNodePath,
@@ -13,10 +13,10 @@ type ResolvedSequencePropEdit = {
13
13
  schema: SaveSequencePropEdit['schema'];
14
14
  sourceEdit: SaveSequencePropEdit['sourceEdit'];
15
15
  };
16
- export declare const convertSequencePropEditToCodemodChange: (edit: Pick<ResolvedSequencePropEdit, "defaultValue" | "key" | "nodePath" | "schema" | "sourceEdit" | "value">) => SequencePropsNodeUpdate;
16
+ export declare const convertSequencePropEditToCodemodChange: (edit: Pick<ResolvedSequencePropEdit, 'nodePath' | 'key' | 'value' | 'defaultValue' | 'schema' | 'sourceEdit'>) => SequencePropsNodeUpdate;
17
17
  export declare const shouldSuppressHmrForSequencePropEdits: (edits: readonly {
18
18
  key: string;
19
- sourceEdit?: import("@remotion/studio-shared").SaveSequencePropSourceEdit | null | undefined;
19
+ sourceEdit?: SaveSequencePropEdit['sourceEdit'];
20
20
  }[]) => boolean;
21
21
  export declare const saveSequencePropsHandler: ApiHandler<SaveSequencePropsRequest, SaveSequencePropsResponse>;
22
22
  export {};
@@ -1,2 +1,3 @@
1
- export declare const getCodemodTimingPrefix: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => string;
2
- export declare const withSourceFileWriteQueue: <T>(fn: () => T | Promise<T>) => Promise<T>;
1
+ import type { LogLevel } from '@remotion/renderer';
2
+ export declare const getCodemodTimingPrefix: (logLevel: LogLevel) => string;
3
+ export declare const withSourceFileWriteQueue: <T>(fn: () => Promise<T> | T) => Promise<T>;
@@ -2,10 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.subscribeToDefaultProps = void 0;
4
4
  const default_props_watchers_1 = require("../default-props-watchers");
5
- const subscribeToDefaultProps = ({ input: { compositionId, clientId }, remotionRoot, entryPoint }) => {
5
+ const subscribeToDefaultProps = ({ input: { compositionId, clientId, symbolicatedStack }, remotionRoot, entryPoint, }) => {
6
6
  return (0, default_props_watchers_1.subscribeToDefaultPropsWatchers)({
7
7
  compositionId,
8
8
  clientId,
9
+ symbolicatedStack,
9
10
  remotionRoot,
10
11
  entryPoint,
11
12
  });
@@ -1,51 +1,72 @@
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.subscribeToSequenceProps = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
4
8
  const sequence_props_watchers_1 = require("../sequence-props-watchers");
5
9
  const can_update_sequence_props_1 = require("./can-update-sequence-props");
6
10
  const subscribeToSequenceProps = ({ input, remotionRoot, logLevel }) => {
7
11
  var _a;
8
- const unresolvedByFile = new Map();
12
+ // Source contents are shared only within this synchronous subscription batch.
13
+ const fileContentsCache = new Map();
14
+ const requestsByFile = new Map();
9
15
  for (const [index, request] of input.requests.entries()) {
10
- if (request.nodePath !== null) {
11
- continue;
12
- }
13
- const unresolved = (_a = unresolvedByFile.get(request.fileName)) !== null && _a !== void 0 ? _a : [];
14
- unresolved.push({ index, line: request.line, column: request.column });
15
- unresolvedByFile.set(request.fileName, unresolved);
16
+ const absolutePath = node_path_1.default.resolve(remotionRoot, request.fileName);
17
+ const indexes = (_a = requestsByFile.get(absolutePath)) !== null && _a !== void 0 ? _a : [];
18
+ indexes.push(index);
19
+ requestsByFile.set(absolutePath, indexes);
16
20
  }
17
- const resolvedNodePaths = new Map();
18
- for (const [fileName, unresolved] of unresolvedByFile) {
19
- try {
20
- const nodePaths = (0, can_update_sequence_props_1.resolveSequencePropsNodePathsFromFilename)({
21
- fileName,
22
- targets: unresolved,
23
- remotionRoot,
24
- });
25
- for (const [index, nodePath] of nodePaths.entries()) {
26
- if (nodePath) {
27
- resolvedNodePaths.set(unresolved[index].index, nodePath);
21
+ const results = [];
22
+ // Finish each file before moving on so large batches do not evict and
23
+ // repeatedly parse the same source snapshot from the bounded AST cache.
24
+ for (const indexes of requestsByFile.values()) {
25
+ const unresolved = indexes
26
+ .filter((index) => input.requests[index].nodePath === null)
27
+ .map((index) => ({
28
+ index,
29
+ line: input.requests[index].line,
30
+ column: input.requests[index].column,
31
+ }));
32
+ const resolvedNodePaths = new Map();
33
+ if (unresolved.length > 0) {
34
+ try {
35
+ const nodePaths = (0, can_update_sequence_props_1.resolveSequencePropsNodePathsFromFilename)({
36
+ fileName: input.requests[indexes[0]].fileName,
37
+ targets: unresolved,
38
+ remotionRoot,
39
+ fileContentsCache,
40
+ });
41
+ for (const [index, nodePath] of nodePaths.entries()) {
42
+ if (nodePath) {
43
+ resolvedNodePaths.set(unresolved[index].index, nodePath);
44
+ }
28
45
  }
29
46
  }
47
+ catch (_b) {
48
+ // Let each subscription produce its usual not-found response.
49
+ }
30
50
  }
31
- catch (_b) {
32
- // Let each subscription produce its usual not-found response.
51
+ for (const index of indexes) {
52
+ const { fileName, line, column, nodePath, componentIdentity, keys, assetKeys, effects, clientId, } = input.requests[index];
53
+ results[index] = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
54
+ fileName,
55
+ line,
56
+ column,
57
+ nodePath,
58
+ resolvedNodePath: resolvedNodePaths.get(index),
59
+ componentIdentity,
60
+ keys,
61
+ assetKeys,
62
+ effects,
63
+ remotionRoot,
64
+ clientId,
65
+ logLevel,
66
+ fileContentsCache,
67
+ });
33
68
  }
34
69
  }
35
- const results = input.requests.map(({ fileName, line, column, nodePath, componentIdentity, keys, assetKeys, effects, clientId, }, index) => (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
36
- fileName,
37
- line,
38
- column,
39
- nodePath,
40
- resolvedNodePath: resolvedNodePaths.get(index),
41
- componentIdentity,
42
- keys,
43
- assetKeys,
44
- effects,
45
- remotionRoot,
46
- clientId,
47
- logLevel,
48
- }));
49
70
  return Promise.resolve({ results });
50
71
  };
51
72
  exports.subscribeToSequenceProps = subscribeToSequenceProps;
@@ -1,3 +1,3 @@
1
- import type { UnsubscribeFromSequencePropsRequest } from '@remotion/studio-shared';
1
+ import type { UnsubscribeFromSequencePropsBatchRequest } from '@remotion/studio-shared';
2
2
  import type { ApiHandler } from '../api-types';
3
- export declare const unsubscribeFromSequenceProps: ApiHandler<UnsubscribeFromSequencePropsRequest, undefined>;
3
+ export declare const unsubscribeFromSequenceProps: ApiHandler<UnsubscribeFromSequencePropsBatchRequest, undefined>;
@@ -2,16 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.unsubscribeFromSequenceProps = void 0;
4
4
  const sequence_props_watchers_1 = require("../sequence-props-watchers");
5
- const unsubscribeFromSequenceProps = ({ input: { fileName, nodePath, clientId, sequenceKeys, assetKeys = [], effectKeys, }, remotionRoot, }) => {
6
- (0, sequence_props_watchers_1.unsubscribeFromSequencePropsWatchers)({
7
- fileName,
8
- nodePath: nodePath.nodePath,
9
- remotionRoot,
10
- clientId,
11
- sequenceKeys,
12
- assetKeys,
13
- effectKeys,
14
- });
5
+ const unsubscribeFromSequenceProps = ({ input, remotionRoot }) => {
6
+ for (const { fileName, nodePath, clientId, sequenceKeys, assetKeys = [], effectKeys, } of input.requests) {
7
+ (0, sequence_props_watchers_1.unsubscribeFromSequencePropsWatchers)({
8
+ fileName,
9
+ nodePath: nodePath.nodePath,
10
+ remotionRoot,
11
+ clientId,
12
+ sequenceKeys,
13
+ assetKeys,
14
+ effectKeys,
15
+ });
16
+ }
15
17
  return Promise.resolve(undefined);
16
18
  };
17
19
  exports.unsubscribeFromSequenceProps = unsubscribeFromSequenceProps;
@@ -0,0 +1,3 @@
1
+ import type { UnwrapNodeRequest, UnwrapNodeResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const unwrapNodeHandler: ApiHandler<UnwrapNodeRequest, UnwrapNodeResponse>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapNodeHandler = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const codemods_1 = require("@remotion/codemods");
6
+ const renderer_1 = require("@remotion/renderer");
7
+ const file_watcher_1 = require("../../file-watcher");
8
+ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
9
+ const format_log_file_location_1 = require("../format-log-file-location");
10
+ const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
11
+ const undo_stack_1 = require("../undo-stack");
12
+ const source_file_write_queue_1 = require("./source-file-write-queue");
13
+ const unwrapNodeHandler = ({ input: { fileName, compositionId, nodePath, dryRun }, remotionRoot, logLevel, }) => {
14
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(() => {
15
+ var _a;
16
+ try {
17
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
18
+ remotionRoot,
19
+ fileName,
20
+ action: 'modify',
21
+ });
22
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
23
+ const canUnwrap = (0, codemods_1.canUnwrapNode)({ input: fileContents, nodePath });
24
+ if (dryRun) {
25
+ return Promise.resolve({
26
+ success: true,
27
+ canUnwrap,
28
+ nodePathMutation: null,
29
+ });
30
+ }
31
+ const result = (0, codemods_1.unwrapNode)({
32
+ project: { files: { [absolutePath]: fileContents }, rootDir: remotionRoot },
33
+ node: { filePath: absolutePath, nodePath },
34
+ });
35
+ const change = result.changes.find(({ filePath }) => filePath === absolutePath);
36
+ if ((change === null || change === void 0 ? void 0 : change.previousContents) !== fileContents ||
37
+ change.nextContents === null) {
38
+ throw new Error('Could not unwrap JSX node');
39
+ }
40
+ const output = change.nextContents;
41
+ const remappings = result.nodePathRemappings.map(({ oldNodePath, newNodePath, oldJsxName, newJsxName }) => ({
42
+ oldNodePath,
43
+ newNodePath,
44
+ oldJsxName,
45
+ newJsxName,
46
+ }));
47
+ const { childNodePath } = result;
48
+ const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([{ absolutePath, remappings }], childNodePath !== null
49
+ ? { compositionId, absolutePath, nodePath: childNodePath }
50
+ : null);
51
+ const line = result.logLine;
52
+ (0, undo_stack_1.pushTransactionToUndoStack)({
53
+ snapshots: [
54
+ {
55
+ filePath: absolutePath,
56
+ oldContents: fileContents,
57
+ newContents: null,
58
+ logLine: line,
59
+ nodePathRemappings: remappings,
60
+ },
61
+ ],
62
+ logLevel,
63
+ remotionRoot,
64
+ description: {
65
+ undoMessage: '↩️ Unwrapping JSX',
66
+ redoMessage: '↪️ Unwrapping JSX',
67
+ },
68
+ entryType: 'unwrap-node',
69
+ suppressHmrOnFileRestore: false,
70
+ undoRedoNavigation: null,
71
+ });
72
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
73
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
74
+ file: absolutePath,
75
+ content: output,
76
+ originatorClientId: undefined,
77
+ metadata: { skipSequencePropsUpdate: true },
78
+ });
79
+ const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
80
+ remotionRoot,
81
+ absolutePath,
82
+ line,
83
+ });
84
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(locationLabel)} Unwrapped JSX`);
85
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[unwrap-node] Wrote ${fileRelativeToRoot}`);
86
+ (0, undo_stack_1.printUndoHint)(logLevel);
87
+ return Promise.resolve({ success: true, canUnwrap, nodePathMutation });
88
+ }
89
+ catch (err) {
90
+ return Promise.resolve({
91
+ success: false,
92
+ reason: err.message,
93
+ stack: (_a = err.stack) !== null && _a !== void 0 ? _a : '',
94
+ });
95
+ }
96
+ });
97
+ };
98
+ exports.unwrapNodeHandler = unwrapNodeHandler;