@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
@@ -6,29 +6,29 @@ const codemods_1 = require("@remotion/codemods");
6
6
  const renderer_1 = require("@remotion/renderer");
7
7
  const file_watcher_1 = require("../../file-watcher");
8
8
  const format_log_file_location_1 = require("../format-log-file-location");
9
- const project_info_1 = require("../project-info");
10
9
  const undo_stack_1 = require("../undo-stack");
11
10
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
12
11
  const can_update_default_props_1 = require("./can-update-default-props");
13
12
  const source_file_write_queue_1 = require("./source-file-write-queue");
14
- const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumPaths }, remotionRoot, entryPoint, logLevel, }) => {
13
+ const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumPaths, symbolicatedStack }, remotionRoot, entryPoint, logLevel, }) => {
15
14
  return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
16
15
  var _a;
17
16
  var _b;
18
17
  try {
19
18
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[update-default-props] Received request for compositionId="${compositionId}"`);
20
- const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
21
- if (!projectInfo.rootFile) {
22
- throw new Error('Cannot find root file in project');
23
- }
24
- (0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
25
- const fileContents = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
19
+ const compositionFile = await (0, can_update_default_props_1.getDefaultPropsFile)({
20
+ symbolicatedStack,
21
+ remotionRoot,
22
+ entryPoint,
23
+ });
24
+ (0, can_update_default_props_1.checkIfTypeScriptFile)(compositionFile);
25
+ const fileContents = (0, node_fs_1.readFileSync)(compositionFile, 'utf-8');
26
26
  const result = (0, codemods_1.setCompositionDefaultProps)({
27
27
  project: {
28
- files: { [projectInfo.rootFile]: fileContents },
28
+ files: { [compositionFile]: fileContents },
29
29
  rootDir: remotionRoot,
30
30
  },
31
- compositionFile: projectInfo.rootFile,
31
+ compositionFile,
32
32
  compositionId,
33
33
  defaultProps: JSON.parse(defaultProps),
34
34
  enumPaths,
@@ -36,7 +36,7 @@ const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumP
36
36
  const { logLine } = result;
37
37
  const output = (_b = (_a = result.changes[0]) === null || _a === void 0 ? void 0 : _a.nextContents) !== null && _b !== void 0 ? _b : fileContents;
38
38
  (0, undo_stack_1.pushToUndoStack)({
39
- filePath: projectInfo.rootFile,
39
+ filePath: compositionFile,
40
40
  oldContents: fileContents,
41
41
  newContents: null,
42
42
  logLevel,
@@ -50,17 +50,17 @@ const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumP
50
50
  suppressHmrOnFileRestore: true,
51
51
  nodePathRemappings: null,
52
52
  });
53
- (0, undo_stack_1.suppressUndoStackInvalidation)(projectInfo.rootFile);
54
- (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(projectInfo.rootFile);
53
+ (0, undo_stack_1.suppressUndoStackInvalidation)(compositionFile);
54
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(compositionFile);
55
55
  (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
56
- file: projectInfo.rootFile,
56
+ file: compositionFile,
57
57
  content: output,
58
58
  originatorClientId: undefined,
59
59
  metadata: null,
60
60
  });
61
61
  const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
62
62
  remotionRoot,
63
- absolutePath: projectInfo.rootFile,
63
+ absolutePath: compositionFile,
64
64
  line: logLine,
65
65
  });
66
66
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Updated default props for "${compositionId}"`);
@@ -1,9 +1,5 @@
1
1
  import type { SequenceNodePathMutation, SequenceNodePathRemapping } from '@remotion/studio-shared';
2
- export declare const broadcastSequenceNodePathMutation: (files: {
2
+ export declare const broadcastSequenceNodePathMutation: (files: Array<{
3
3
  absolutePath: string;
4
4
  remappings: SequenceNodePathRemapping[];
5
- }[], timelineSelection: {
6
- compositionId: string;
7
- absolutePath: string;
8
- nodePath: import("remotion").SequenceNodePath;
9
- } | null) => SequenceNodePathMutation;
5
+ }>, timelineSelection: SequenceNodePathMutation['timelineSelection']) => SequenceNodePathMutation;
@@ -1,18 +1,20 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  import { type SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
2
- import type { SequenceNodePath } from 'remotion';
3
- export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, resolvedNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, }: {
3
+ import type { JsxComponentIdentity, SequenceNodePath } from 'remotion';
4
+ export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, resolvedNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, fileContentsCache, }: {
4
5
  fileName: string;
5
6
  line: number;
6
7
  column: number;
7
8
  nodePath: SequenceNodePath | null;
8
- resolvedNodePath?: SequenceNodePath | null | undefined;
9
- componentIdentity: string | null;
9
+ resolvedNodePath?: SequenceNodePath | null;
10
+ componentIdentity: JsxComponentIdentity | null;
10
11
  keys: string[];
11
12
  assetKeys: string[];
12
13
  effects: string[][];
13
14
  remotionRoot: string;
14
15
  clientId: string;
15
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
16
+ logLevel: LogLevel;
17
+ fileContentsCache: Map<string, string> | null;
16
18
  }) => SubscribeToSequencePropsResponse;
17
19
  export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, assetKeys, effectKeys, }: {
18
20
  fileName: string;
@@ -15,7 +15,7 @@ const node_path_cache_1 = require("./node-path-cache");
15
15
  const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
16
16
  const sequencePropsWatchers = {};
17
17
  const getWatcherKey = (nodePath, assetKeys) => `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath)}:${assetKeys.join('\0')}`;
18
- const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, resolvedNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, }) => {
18
+ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, resolvedNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, fileContentsCache, }) => {
19
19
  if (preferredNodePath) {
20
20
  try {
21
21
  const fromNodePath = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
@@ -26,6 +26,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, res
26
26
  assetKeys,
27
27
  effects,
28
28
  remotionRoot,
29
+ fileContentsCache,
29
30
  });
30
31
  return {
31
32
  status: fromNodePath,
@@ -59,6 +60,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, res
59
60
  assetKeys,
60
61
  effects,
61
62
  remotionRoot,
63
+ fileContentsCache,
62
64
  });
63
65
  }
64
66
  catch (error) {
@@ -94,6 +96,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, res
94
96
  assetKeys,
95
97
  effects,
96
98
  remotionRoot,
99
+ fileContentsCache,
97
100
  }),
98
101
  nodePath: {
99
102
  absolutePath: node_path_1.default.resolve(remotionRoot, fileName),
@@ -122,10 +125,11 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, res
122
125
  effects,
123
126
  remotionRoot,
124
127
  logLevel,
128
+ fileContentsCache,
125
129
  });
126
130
  return status;
127
131
  };
128
- const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, resolvedNodePath = null, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, }) => {
132
+ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, resolvedNodePath = null, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, fileContentsCache, }) => {
129
133
  var _a;
130
134
  const initialResult = getSequencePropsStatus({
131
135
  fileName,
@@ -139,13 +143,19 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
139
143
  effects,
140
144
  remotionRoot,
141
145
  logLevel,
146
+ fileContentsCache,
142
147
  });
143
148
  if (!initialResult.success) {
144
149
  return initialResult;
145
150
  }
146
151
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
147
- // Cache the resolved nodePath for future lookups with stale source maps
148
- (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath.nodePath);
152
+ // A preferred path may have been remapped while these coordinates still
153
+ // come from the previous bundle. Caching that pair can make a later mount
154
+ // at the same location inherit a different sibling's props after Refresh.
155
+ // Only a location-based subscription can establish a location cache entry.
156
+ if (preferredNodePath === null) {
157
+ (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath.nodePath);
158
+ }
149
159
  const { nodePath } = initialResult;
150
160
  const watcherKey = getWatcherKey(nodePath, assetKeys);
151
161
  const existingWatcher = (_a = sequencePropsWatchers[clientId]) === null || _a === void 0 ? void 0 : _a[watcherKey];
@@ -10,7 +10,7 @@ export declare const serveStatic: ({ root, path, req, res, allowOutsidePublicFol
10
10
  root: string;
11
11
  path: string;
12
12
  req: IncomingMessage;
13
- res: ServerResponse<IncomingMessage>;
13
+ res: ServerResponse;
14
14
  allowOutsidePublicFolder: boolean;
15
15
  allowRemotionConvertCors: boolean;
16
16
  }) => Promise<void>;
@@ -82,12 +82,22 @@ const serveStatic = async function ({ root, path, req, res, allowOutsidePublicFo
82
82
  res.end();
83
83
  return;
84
84
  }
85
+ if (res.destroyed) {
86
+ return;
87
+ }
85
88
  const hasRange = req.headers.range && lstat.size;
86
89
  if (!hasRange) {
87
- const readStream = (0, node_fs_1.createReadStream)(path);
88
90
  res.setHeader('content-type', renderer_1.RenderInternals.mimeLookup(path) || 'application/octet-stream');
89
91
  res.setHeader('content-length', lstat.size);
90
92
  res.writeHead(200);
93
+ if (req.method === 'HEAD') {
94
+ res.end();
95
+ return;
96
+ }
97
+ const readStream = (0, node_fs_1.createReadStream)(path);
98
+ res.once('close', () => {
99
+ readStream.destroy();
100
+ });
91
101
  readStream.pipe(res);
92
102
  return;
93
103
  }
@@ -101,10 +111,17 @@ const serveStatic = async function ({ root, path, req, res, allowOutsidePublicFo
101
111
  }));
102
112
  res.setHeader('content-length', end - start + 1);
103
113
  res.writeHead(206);
114
+ if (req.method === 'HEAD') {
115
+ res.end();
116
+ return;
117
+ }
104
118
  const readStream = (0, node_fs_1.createReadStream)(path, {
105
119
  start,
106
120
  end,
107
121
  });
122
+ res.once('close', () => {
123
+ readStream.destroy();
124
+ });
108
125
  readStream.pipe(res);
109
126
  return;
110
127
  }
@@ -1,5 +1,5 @@
1
1
  import type { BundlerOverrideFn, RspackOverrideFn, WebpackOverrideFn } from '@remotion/bundler';
2
- import type { DefaultEditor } from '@remotion/renderer';
2
+ import type { DefaultCodingAgent, DefaultEditor, LogLevel } from '@remotion/renderer';
3
3
  import type { GitSource, RenderDefaults, RenderJob, StudioRuntimeConfig } from '@remotion/studio-shared';
4
4
  import type { QueueMethods } from './api-types';
5
5
  import type { LiveEventsServer } from './live-events';
@@ -28,7 +28,7 @@ export declare const startServer: (options: {
28
28
  staticHashPrefix: string;
29
29
  outputHash: string;
30
30
  outputHashPrefix: string;
31
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
31
+ logLevel: LogLevel;
32
32
  getRenderQueue: () => RenderJob[];
33
33
  getRenderDefaults: () => RenderDefaults;
34
34
  getNumberOfAudioTags: () => number;
@@ -43,7 +43,7 @@ export declare const startServer: (options: {
43
43
  forceNew: boolean;
44
44
  rspack: boolean;
45
45
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
46
- getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
46
+ getDefaultCodingAgent: () => DefaultCodingAgent | null;
47
47
  getDefaultEditor: () => DefaultEditor | null;
48
48
  configFile: string | null;
49
49
  }) => Promise<StartServerResult>;
@@ -7,5 +7,5 @@ export declare const handleStudioProtocolDiscovery: ({ gitSource, liveEventsServ
7
7
  readonly liveEventsServer: LiveEventsServer;
8
8
  readonly remotionRoot: string;
9
9
  readonly request: IncomingMessage;
10
- readonly response: ServerResponse<IncomingMessage>;
10
+ readonly response: ServerResponse;
11
11
  }) => Promise<void>;
@@ -6,6 +6,6 @@ export declare const handleStudioProtocolElementLibrary: ({ configFile, focusStu
6
6
  readonly focusStudioTab: FocusStudioTab;
7
7
  readonly liveEventsServer: LiveEventsServer;
8
8
  readonly request: IncomingMessage;
9
- readonly response: ServerResponse<IncomingMessage>;
9
+ readonly response: ServerResponse;
10
10
  }) => Promise<void>;
11
11
  export {};
@@ -5,6 +5,6 @@ export declare const handleStudioProtocolInstall: ({ focusStudioTab, liveEventsS
5
5
  readonly focusStudioTab: FocusStudioTab;
6
6
  readonly liveEventsServer: LiveEventsServer;
7
7
  readonly request: IncomingMessage;
8
- readonly response: ServerResponse<IncomingMessage>;
8
+ readonly response: ServerResponse;
9
9
  }) => Promise<void>;
10
10
  export {};
@@ -6,6 +6,6 @@ export declare const handleStudioProtocolLicenseKey: ({ configFile, focusStudioT
6
6
  readonly focusStudioTab: FocusStudioTab;
7
7
  readonly liveEventsServer: LiveEventsServer;
8
8
  readonly request: IncomingMessage;
9
- readonly response: ServerResponse<IncomingMessage>;
9
+ readonly response: ServerResponse;
10
10
  }) => Promise<void>;
11
11
  export {};
@@ -2,9 +2,9 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  export declare const getAllowedStudioProtocolOrigin: (request: IncomingMessage) => string | null;
3
3
  export declare const setStudioProtocolCorsHeaders: ({ request, response, }: {
4
4
  readonly request: IncomingMessage;
5
- readonly response: ServerResponse<IncomingMessage>;
5
+ readonly response: ServerResponse;
6
6
  }) => void;
7
7
  export declare const handleStudioProtocolOptions: ({ request, response, }: {
8
8
  readonly request: IncomingMessage;
9
- readonly response: ServerResponse<IncomingMessage>;
9
+ readonly response: ServerResponse;
10
10
  }) => Promise<void>;
@@ -2,6 +2,6 @@ import type { ServerResponse } from 'node:http';
2
2
  export declare const writeStudioProtocolError: ({ code, message, response, status, }: {
3
3
  readonly code: string;
4
4
  readonly message: string;
5
- readonly response: ServerResponse<import("http").IncomingMessage>;
5
+ readonly response: ServerResponse;
6
6
  readonly status: number;
7
7
  }) => void;
@@ -4,7 +4,7 @@ export interface UndoEntryDescription {
4
4
  undoMessage: string;
5
5
  redoMessage: string;
6
6
  }
7
- type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-nodes' | 'duplicate-nodes' | 'wrap-node' | 'precompose-jsx-nodes' | 'split-sequences' | 'split-video-from-audio' | 'insert-basic-captions' | 'replace-video-source' | 'insert-composition-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-or-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
7
+ type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-nodes' | 'duplicate-nodes' | 'wrap-node' | 'unwrap-node' | 'precompose-jsx-nodes' | 'split-sequences' | 'split-video-from-audio' | 'insert-basic-captions' | 'replace-video-source' | 'insert-composition-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-or-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
8
8
  type UndoEntrySnapshot = {
9
9
  filePath: string;
10
10
  oldContents: string | null;
@@ -24,7 +24,7 @@ type UndoEntry = {
24
24
  entryType: UndoEntryType;
25
25
  undoRedoNavigation: UndoRedoNavigation | null;
26
26
  };
27
- export declare function pushToUndoStack({ filePath, oldContents, newContents, logLevel, remotionRoot, logLine, description, entryType, suppressHmrOnFileRestore, nodePathRemappings }: {
27
+ export declare function pushToUndoStack({ filePath, oldContents, newContents, logLevel, remotionRoot, logLine, description, entryType, suppressHmrOnFileRestore, nodePathRemappings, }: {
28
28
  filePath: string;
29
29
  oldContents: string;
30
30
  newContents: string | null;
@@ -36,7 +36,7 @@ export declare function pushToUndoStack({ filePath, oldContents, newContents, lo
36
36
  suppressHmrOnFileRestore: boolean;
37
37
  nodePathRemappings: SequenceNodePathRemapping[] | null;
38
38
  }): void;
39
- export declare function pushTransactionToUndoStack({ snapshots, logLevel, remotionRoot, description, entryType, suppressHmrOnFileRestore, undoRedoNavigation }: {
39
+ export declare function pushTransactionToUndoStack({ snapshots, logLevel, remotionRoot, description, entryType, suppressHmrOnFileRestore, undoRedoNavigation, }: {
40
40
  snapshots: Array<{
41
41
  filePath: string;
42
42
  oldContents: string | null;
@@ -52,7 +52,7 @@ export declare function pushTransactionToUndoStack({ snapshots, logLevel, remoti
52
52
  undoRedoNavigation: UndoRedoNavigation | null;
53
53
  }): void;
54
54
  export declare function printUndoHint(logLevel: LogLevel): void;
55
- export declare function pushToRedoStack({ filePath, oldContents, newContents, logLine, description, entryType, suppressHmrOnFileRestore }: {
55
+ export declare function pushToRedoStack({ filePath, oldContents, newContents, logLine, description, entryType, suppressHmrOnFileRestore, }: {
56
56
  filePath: string;
57
57
  oldContents: string;
58
58
  newContents: string | null;
@@ -89,10 +89,14 @@ function pushTransactionToUndoStack({ snapshots, logLevel, remotionRoot, descrip
89
89
  undoRedoNavigation,
90
90
  });
91
91
  undoStack.push(entry);
92
+ const discardedEntries = undoStack.length > MAX_ENTRIES || redoStack.length > 0;
92
93
  if (undoStack.length > MAX_ENTRIES) {
93
94
  undoStack.shift();
94
95
  }
95
96
  redoStack.length = 0;
97
+ if (discardedEntries) {
98
+ cleanupWatchers();
99
+ }
96
100
  renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray(`Undo stack: added entry for ${entry.filePath} (${undoStack.length} items)`));
97
101
  for (const filePath of getEntryFilePaths(entry)) {
98
102
  ensureWatching(filePath);
@@ -125,6 +129,7 @@ function pushToRedoStack({ filePath, oldContents, newContents, logLine, descript
125
129
  redoStack.push(entry);
126
130
  if (redoStack.length > MAX_ENTRIES) {
127
131
  redoStack.shift();
132
+ cleanupWatchers();
128
133
  }
129
134
  renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: storedLogLevel }, renderer_1.RenderInternals.chalk.gray(`Redo stack: added entry for ${entry.filePath} (${redoStack.length} items)`));
130
135
  for (const watchedFilePath of getEntryFilePaths(entry)) {
@@ -202,6 +207,7 @@ function cleanupWatchers() {
202
207
  if (!filesInStacks.has(filePath)) {
203
208
  watcher.unwatch();
204
209
  watchers.delete(filePath);
210
+ suppressedWrites.delete(filePath);
205
211
  }
206
212
  }
207
213
  }
@@ -257,6 +263,7 @@ function popUndo() {
257
263
  }));
258
264
  if (redoStack.length > MAX_ENTRIES) {
259
265
  redoStack.shift();
266
+ cleanupWatchers();
260
267
  }
261
268
  const files = entry.snapshots.flatMap((snapshot) => {
262
269
  if (snapshot.nodePathRemappings === null) {
@@ -328,6 +335,7 @@ function popRedo() {
328
335
  const snapshotsWithNewContents = [];
329
336
  for (const snapshot of entry.snapshots) {
330
337
  if (snapshot.newContents === null) {
338
+ cleanupWatchers();
331
339
  return { success: false, reason: 'Redo entry is incomplete' };
332
340
  }
333
341
  snapshotsWithNewContents.push({
@@ -344,6 +352,7 @@ function popRedo() {
344
352
  }));
345
353
  if (undoStack.length > MAX_ENTRIES) {
346
354
  undoStack.shift();
355
+ cleanupWatchers();
347
356
  }
348
357
  const files = snapshotsWithNewContents.flatMap((snapshot) => {
349
358
  if (snapshot.nodePathRemappings === null) {
@@ -1,9 +1,10 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  import type { UpdateAvailableResponse } from '@remotion/studio-shared';
2
3
  export declare const isUpdateAvailable: ({ remotionRoot, currentVersion, logLevel, getLatestVersion, }: {
3
4
  remotionRoot: string;
4
5
  currentVersion: string;
5
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
6
+ logLevel: LogLevel;
6
7
  getLatestVersion: (() => Promise<string>) | null;
7
8
  }) => Promise<UpdateAvailableResponse>;
8
9
  export declare const getRemotionVersion: () => any;
9
- export declare const isUpdateAvailableWithTimeout: (remotionRoot: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn") => Promise<UpdateAvailableResponse>;
10
+ export declare const isUpdateAvailableWithTimeout: (remotionRoot: string, logLevel: LogLevel) => Promise<UpdateAvailableResponse>;
@@ -1,2 +1,2 @@
1
- export declare const remotionSkillNames: readonly ["remotion-best-practices", "remotion-captions", "remotion-create", "remotion-docs", "remotion-interactivity", "remotion-maps", "remotion-markup", "remotion-multimedia", "remotion-render", "remotion-saas", "remotion-studio", "remotion-upgrade"];
1
+ export declare const remotionSkillNames: readonly ['remotion-best-practices', 'remotion-captions', 'remotion-create', 'remotion-docs', 'remotion-interactivity', 'remotion-maps', 'remotion-markup', 'remotion-multimedia', 'remotion-render', 'remotion-saas', 'remotion-studio', 'remotion-upgrade'];
2
2
  export type RemotionSkillName = (typeof remotionSkillNames)[number];
package/dist/routes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- import type { DefaultEditor } from '@remotion/renderer';
2
+ import type { DefaultCodingAgent, DefaultEditor, LogLevel } from '@remotion/renderer';
3
3
  import type { GitSource, RenderDefaults, RenderJob, StudioRuntimeConfig } from '@remotion/studio-shared';
4
4
  import type { QueueMethods } from './preview-server/api-types';
5
5
  import type { LiveEventsServer } from './preview-server/live-events';
@@ -9,14 +9,14 @@ export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash,
9
9
  outputHash: string;
10
10
  outputHashPrefix: string;
11
11
  request: IncomingMessage;
12
- response: ServerResponse<IncomingMessage>;
12
+ response: ServerResponse;
13
13
  liveEventsServer: LiveEventsServer;
14
14
  getCurrentInputProps: () => object;
15
15
  getEnvVariables: () => Record<string, string>;
16
16
  remotionRoot: string;
17
17
  entryPoint: string;
18
18
  publicDir: string;
19
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
19
+ logLevel: LogLevel;
20
20
  getRenderQueue: () => RenderJob[];
21
21
  getRenderDefaults: () => RenderDefaults;
22
22
  getNumberOfAudioTags: () => number;
@@ -28,7 +28,7 @@ export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash,
28
28
  getPreviewSampleRate: () => number | null;
29
29
  enableCrossSiteIsolation: boolean;
30
30
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
31
- getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
31
+ getDefaultCodingAgent: () => DefaultCodingAgent | null;
32
32
  getDefaultEditor: () => DefaultEditor | null;
33
33
  configFile: string | null;
34
34
  invalidateBundle: () => Promise<void>;
@@ -1,2 +1,3 @@
1
+ import type { LogLevel } from '@remotion/renderer';
1
2
  export declare const setServerReadyComment: (newMessage: string) => void;
2
- export declare const printServerReadyComment: (prefix: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn") => void;
3
+ export declare const printServerReadyComment: (prefix: string, logLevel: LogLevel) => void;
@@ -1,5 +1,5 @@
1
1
  import type { BundlerOverrideFn, RspackOverrideFn, WebpackOverrideFn } from '@remotion/bundler';
2
- import type { DefaultEditor } from '@remotion/renderer';
2
+ import type { DefaultCodingAgent, DefaultEditor, LogLevel } from '@remotion/renderer';
3
3
  import type { GitSource, RenderDefaults, RenderJob, StudioRuntimeConfig } from '@remotion/studio-shared';
4
4
  import type { QueueMethods } from './preview-server/api-types';
5
5
  export type StartStudioResult = {
@@ -13,7 +13,7 @@ export type StartStudioResult = {
13
13
  export declare const startStudio: ({ browserArgs, browserFlag, shouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, remotionRoot, relativePublicDir, bundlerOverride, rspackOverride, webpackOverride, poll, getRenderDefaults, getRenderQueue, getNumberOfAudioTags, queueMethods, previewEntry, gitSource, binariesDirectory, forceIPv4, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, forceNew, rspack, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, }: {
14
14
  browserArgs: string;
15
15
  browserFlag: string;
16
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
16
+ logLevel: LogLevel;
17
17
  shouldOpenBrowser: boolean;
18
18
  fullEntryPath: string;
19
19
  getCurrentInputProps: () => object;
@@ -40,7 +40,7 @@ export declare const startStudio: ({ browserArgs, browserFlag, shouldOpenBrowser
40
40
  forceNew: boolean;
41
41
  rspack: boolean;
42
42
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
43
- getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
43
+ getDefaultCodingAgent: () => DefaultCodingAgent | null;
44
44
  getDefaultEditor: () => DefaultEditor | null;
45
45
  configFile: string | null;
46
46
  }) => Promise<StartStudioResult>;
@@ -1,12 +1,12 @@
1
- import type { DefaultEditor } from '@remotion/renderer';
1
+ import type { DefaultCodingAgent, DefaultEditor, LogLevel } from '@remotion/renderer';
2
2
  export declare const registerStudioShortcuts: ({ browserArgs, browserFlag, url, logLevel, remotionRoot, getDefaultEditor, getDefaultCodingAgent, }: {
3
3
  browserArgs: string;
4
4
  browserFlag: string;
5
5
  url: string;
6
- logLevel: "error" | "info" | "trace" | "verbose" | "warn";
6
+ logLevel: LogLevel;
7
7
  remotionRoot: string;
8
8
  getDefaultEditor: () => DefaultEditor | null;
9
- getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
9
+ getDefaultCodingAgent: () => DefaultCodingAgent | null;
10
10
  }) => {
11
11
  registered: boolean;
12
12
  cleanup: () => void;
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.536",
6
+ "version": "4.0.538",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -11,7 +11,7 @@
11
11
  "test": "bun test src",
12
12
  "formatting": "oxfmt src --check",
13
13
  "format": "oxfmt src",
14
- "make": "tsgo -d"
14
+ "make": "tsc -d"
15
15
  },
16
16
  "author": "Jonny Burger <jonny@remotion.dev>",
17
17
  "contributors": [],
@@ -23,7 +23,7 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@remotion/studio-protocol": "4.0.536",
26
+ "@remotion/studio-protocol": "4.0.538",
27
27
  "@babel/types": "7.24.0",
28
28
  "@babel/parser": "7.24.1",
29
29
  "@svgr/core": "8.1.0",
@@ -31,12 +31,12 @@
31
31
  "kiwi-schema": "0.5.0",
32
32
  "semver": "7.5.3",
33
33
  "zod": "4.5.4",
34
- "remotion": "4.0.536",
34
+ "remotion": "4.0.538",
35
35
  "recast": "0.23.21",
36
- "@remotion/bundler": "4.0.536",
37
- "@remotion/renderer": "4.0.536",
38
- "@remotion/codemods": "4.0.536",
39
- "@remotion/studio-shared": "4.0.536",
36
+ "@remotion/bundler": "4.0.538",
37
+ "@remotion/renderer": "4.0.538",
38
+ "@remotion/codemods": "4.0.538",
39
+ "@remotion/studio-shared": "4.0.538",
40
40
  "memfs": "3.4.3",
41
41
  "open": "8.4.2"
42
42
  },
@@ -44,11 +44,11 @@
44
44
  "ast-types": "0.16.1",
45
45
  "react": "19.2.3",
46
46
  "@types/semver": "7.5.3",
47
- "@remotion/eslint-config-internal": "4.0.536",
47
+ "@remotion/eslint-config-internal": "4.0.538",
48
48
  "eslint": "9.19.0",
49
49
  "prettier": "3.8.1",
50
50
  "@types/node": "20.12.14",
51
- "@typescript/native-preview": "7.0.0-dev.20260217.1"
51
+ "typescript": "7.1.0-beta"
52
52
  },
53
53
  "exports": {
54
54
  ".": "./dist/index.js",