@remotion/studio-server 4.0.419 → 4.0.421

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.
@@ -0,0 +1,13 @@
1
+ type RemotionDetectionResult = {
2
+ type: 'match';
3
+ } | {
4
+ type: 'mismatch';
5
+ } | {
6
+ type: 'not-remotion';
7
+ };
8
+ export declare const detectRemotionServer: ({ port, cwd, hostname, }: {
9
+ port: number;
10
+ cwd: string;
11
+ hostname: string;
12
+ }) => Promise<RemotionDetectionResult>;
13
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.detectRemotionServer = void 0;
7
+ const http_1 = __importDefault(require("http"));
8
+ const detectRemotionServer = ({ port, cwd, hostname, }) => {
9
+ return new Promise((resolve) => {
10
+ const req = http_1.default.get({
11
+ hostname,
12
+ port,
13
+ path: '/__remotion_config',
14
+ timeout: 1000,
15
+ }, (res) => {
16
+ if (res.statusCode !== 200) {
17
+ res.resume();
18
+ return resolve({ type: 'not-remotion' });
19
+ }
20
+ let data = '';
21
+ res.on('data', (chunk) => {
22
+ data += chunk;
23
+ });
24
+ res.on('error', () => {
25
+ resolve({ type: 'not-remotion' });
26
+ });
27
+ res.on('end', () => {
28
+ try {
29
+ const json = JSON.parse(data);
30
+ if (json.isRemotion !== true) {
31
+ return resolve({ type: 'not-remotion' });
32
+ }
33
+ // Normalize paths for comparison to avoid issues with different separators or casing on Windows
34
+ const normalize = (p) => p.replace(/\\/g, '/').toLowerCase();
35
+ if (normalize(json.cwd) === normalize(cwd)) {
36
+ return resolve({ type: 'match' });
37
+ }
38
+ return resolve({ type: 'mismatch' });
39
+ }
40
+ catch (_a) {
41
+ resolve({ type: 'not-remotion' });
42
+ }
43
+ });
44
+ });
45
+ req.on('error', () => resolve({ type: 'not-remotion' }));
46
+ req.on('timeout', () => {
47
+ req.destroy();
48
+ });
49
+ });
50
+ };
51
+ exports.detectRemotionServer = detectRemotionServer;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { ApiRoutes, CopyStillToClipboardRequest, getDefaultOutLocation, OpenInFi
2
2
  export type { AggregateRenderProgress, BundlingState, CopyingState, DownloadProgress, HotMiddlewareOptions, JobProgressCallback, ModuleMap, PackageManager, ProjectInfo, RenderingProgressInput, RenderJob, RenderJobWithCleanup, RequiredChromiumOptions, StitchingProgressInput, UiOpenGlOptions, } from '@remotion/studio-shared';
3
3
  import { AnsiDiff } from './ansi-diff';
4
4
  export declare const StudioServerInternals: {
5
- startStudio: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, }: {
5
+ startStudio: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, forceNew, }: {
6
6
  browserArgs: string;
7
7
  browserFlag: string;
8
8
  logLevel: import("@remotion/renderer").LogLevel;
@@ -31,7 +31,8 @@ export declare const StudioServerInternals: {
31
31
  binariesDirectory: string | null;
32
32
  forceIPv4: boolean;
33
33
  askAIEnabled: boolean;
34
- }) => Promise<void>;
34
+ forceNew: boolean;
35
+ }) => Promise<import("./start-studio").StartStudioResult>;
35
36
  getRemotionVersion: () => any;
36
37
  waitForLiveEventsListener: () => Promise<import("./preview-server/live-events").LiveEventsServer>;
37
38
  lockFilePaths: {
@@ -70,11 +71,6 @@ export declare const StudioServerInternals: {
70
71
  newContents: string;
71
72
  changesMade: import("./codemods/recast-mods").Change[];
72
73
  };
73
- openBrowser: ({ url, browserFlag, browserArgs, }: {
74
- url: string;
75
- browserFlag: string | undefined;
76
- browserArgs: string | undefined;
77
- }) => Promise<boolean | import("child_process").ChildProcess>;
78
74
  getInstalledDependencies: (remotionRoot: string) => {
79
75
  dependencies: string[];
80
76
  devDependencies: string[];
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@ const studio_shared_1 = require("@remotion/studio-shared");
5
5
  var studio_shared_2 = require("@remotion/studio-shared");
6
6
  Object.defineProperty(exports, "getDefaultOutLocation", { enumerable: true, get: function () { return studio_shared_2.getDefaultOutLocation; } });
7
7
  const ansi_diff_1 = require("./ansi-diff");
8
- const better_opn_1 = require("./better-opn");
9
8
  const duplicate_composition_1 = require("./codemods/duplicate-composition");
10
9
  const file_watcher_1 = require("./file-watcher");
11
10
  const get_latest_remotion_version_1 = require("./get-latest-remotion-version");
@@ -29,7 +28,6 @@ exports.StudioServerInternals = {
29
28
  AnsiDiff: ansi_diff_1.AnsiDiff,
30
29
  formatBytes: studio_shared_1.formatBytes,
31
30
  parseAndApplyCodemod: duplicate_composition_1.parseAndApplyCodemod,
32
- openBrowser: better_opn_1.openBrowser,
33
31
  getInstalledDependencies: get_installed_dependencies_1.getInstalledDependencies,
34
32
  getInstallCommand: install_command_1.getInstallCommand,
35
33
  };
@@ -0,0 +1,11 @@
1
+ import type { LogLevel } from '@remotion/renderer';
2
+ export declare const maybeOpenBrowser: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, parsedCliOpen, url, logLevel, }: {
3
+ browserArgs: string;
4
+ browserFlag: string;
5
+ configValueShouldOpenBrowser: boolean;
6
+ parsedCliOpen: boolean;
7
+ url: string;
8
+ logLevel: LogLevel;
9
+ }) => Promise<{
10
+ didOpenBrowser: boolean;
11
+ }>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maybeOpenBrowser = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
5
+ const better_opn_1 = require("./better-opn");
6
+ const getShouldOpenBrowser = ({ configValueShouldOpenBrowser, parsedCliOpen, }) => {
7
+ var _a;
8
+ if (parsedCliOpen === false) {
9
+ return {
10
+ shouldOpenBrowser: false,
11
+ reasonForBrowserDecision: '--no-open specified',
12
+ };
13
+ }
14
+ if (((_a = process.env.BROWSER) !== null && _a !== void 0 ? _a : '').toLowerCase() === 'none') {
15
+ return {
16
+ shouldOpenBrowser: false,
17
+ reasonForBrowserDecision: 'env BROWSER=none was set',
18
+ };
19
+ }
20
+ if (configValueShouldOpenBrowser === false) {
21
+ return { shouldOpenBrowser: false, reasonForBrowserDecision: 'Config file' };
22
+ }
23
+ return { shouldOpenBrowser: true, reasonForBrowserDecision: 'default' };
24
+ };
25
+ const maybeOpenBrowser = async ({ browserArgs, browserFlag, configValueShouldOpenBrowser, parsedCliOpen, url, logLevel, }) => {
26
+ const { reasonForBrowserDecision, shouldOpenBrowser } = getShouldOpenBrowser({
27
+ configValueShouldOpenBrowser,
28
+ parsedCliOpen,
29
+ });
30
+ if (shouldOpenBrowser) {
31
+ await (0, better_opn_1.openBrowser)({
32
+ url,
33
+ browserArgs,
34
+ browserFlag,
35
+ });
36
+ }
37
+ else {
38
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `Not opening browser, reason: ${reasonForBrowserDecision}`);
39
+ }
40
+ return { didOpenBrowser: shouldOpenBrowser };
41
+ };
42
+ exports.maybeOpenBrowser = maybeOpenBrowser;
@@ -3,6 +3,15 @@ import type { LogLevel } from '@remotion/renderer';
3
3
  import type { GitSource, RenderDefaults, RenderJob } from '@remotion/studio-shared';
4
4
  import type { QueueMethods } from './api-types';
5
5
  import type { LiveEventsServer } from './live-events';
6
+ export type StartServerResult = {
7
+ type: 'started';
8
+ port: number;
9
+ liveEventsServer: LiveEventsServer;
10
+ close: () => Promise<void>;
11
+ } | {
12
+ type: 'already-running';
13
+ port: number;
14
+ };
6
15
  export declare const startServer: (options: {
7
16
  entry: string;
8
17
  userDefinedComponent: string;
@@ -32,8 +41,5 @@ export declare const startServer: (options: {
32
41
  audioLatencyHint: AudioContextLatencyCategory | null;
33
42
  enableCrossSiteIsolation: boolean;
34
43
  askAIEnabled: boolean;
35
- }) => Promise<{
36
- port: number;
37
- liveEventsServer: LiveEventsServer;
38
- close: () => Promise<void>;
39
- }>;
44
+ forceNew: boolean;
45
+ }) => Promise<StartServerResult>;
@@ -7,19 +7,32 @@ exports.startServer = void 0;
7
7
  const bundler_1 = require("@remotion/bundler");
8
8
  const renderer_1 = require("@remotion/renderer");
9
9
  const node_http_1 = __importDefault(require("node:http"));
10
+ const detect_remotion_server_1 = require("../detect-remotion-server");
10
11
  const routes_1 = require("../routes");
11
12
  const dev_middleware_1 = require("./dev-middleware");
12
13
  const hot_middleware_1 = require("./hot-middleware");
13
14
  const live_events_1 = require("./live-events");
14
15
  const startServer = async (options) => {
15
16
  var _a, _b, _c;
17
+ const desiredPort = (_b = (_a = options === null || options === void 0 ? void 0 : options.port) !== null && _a !== void 0 ? _a : (process.env.PORT ? Number(process.env.PORT) : undefined)) !== null && _b !== void 0 ? _b : undefined;
18
+ const portConfig = renderer_1.RenderInternals.getPortConfig(options.forceIPv4);
19
+ const onPortUnavailable = options.forceNew
20
+ ? undefined
21
+ : async (port) => {
22
+ const detection = await (0, detect_remotion_server_1.detectRemotionServer)({
23
+ port,
24
+ cwd: options.remotionRoot,
25
+ hostname: portConfig.hostsToTry[0],
26
+ });
27
+ return detection.type === 'match' ? 'stop' : 'continue';
28
+ };
16
29
  const [, config] = await bundler_1.BundlerInternals.webpackConfig({
17
30
  entry: options.entry,
18
31
  userDefinedComponent: options.userDefinedComponent,
19
32
  outDir: null,
20
33
  environment: 'development',
21
34
  webpackOverride: options === null || options === void 0 ? void 0 : options.webpackOverride,
22
- maxTimelineTracks: (_a = options === null || options === void 0 ? void 0 : options.maxTimelineTracks) !== null && _a !== void 0 ? _a : null,
35
+ maxTimelineTracks: (_c = options === null || options === void 0 ? void 0 : options.maxTimelineTracks) !== null && _c !== void 0 ? _c : null,
23
36
  remotionRoot: options.remotionRoot,
24
37
  keyboardShortcutsEnabled: options.keyboardShortcutsEnabled,
25
38
  experimentalClientSideRenderingEnabled: options.experimentalClientSideRenderingEnabled,
@@ -86,35 +99,47 @@ const startServer = async (options) => {
86
99
  }
87
100
  });
88
101
  });
89
- const desiredPort = (_c = (_b = options === null || options === void 0 ? void 0 : options.port) !== null && _b !== void 0 ? _b : (process.env.PORT ? Number(process.env.PORT) : undefined)) !== null && _c !== void 0 ? _c : undefined;
90
102
  const maxTries = 5;
91
- const portConfig = renderer_1.RenderInternals.getPortConfig(options.forceIPv4);
92
103
  for (let i = 0; i < maxTries; i++) {
93
104
  try {
105
+ const { port, unlockPort, didUsePort } = await renderer_1.RenderInternals.getDesiredPort({
106
+ desiredPort,
107
+ from: 3000,
108
+ to: 3100,
109
+ hostsToTry: portConfig.hostsToTry,
110
+ onPortUnavailable,
111
+ });
112
+ if (didUsePort) {
113
+ unlockPort();
114
+ await Promise.all([
115
+ new Promise((resolve) => {
116
+ server.close(() => resolve());
117
+ }),
118
+ new Promise((resolve) => {
119
+ compiler.close(() => resolve());
120
+ }),
121
+ ]);
122
+ return {
123
+ type: 'already-running',
124
+ port,
125
+ };
126
+ }
94
127
  const selectedPort = await new Promise((resolve, reject) => {
95
- renderer_1.RenderInternals.getDesiredPort({
96
- desiredPort,
97
- from: 3000,
98
- to: 3100,
99
- hostsToTry: portConfig.hostsToTry,
100
- })
101
- .then(({ port, unlockPort }) => {
102
- renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: options.logLevel }, `Binding server to host ${portConfig.host}, port ${port}`);
103
- server.listen({
104
- port,
105
- host: portConfig.host,
106
- });
107
- server.on('listening', () => {
108
- resolve(port);
109
- return unlockPort();
110
- });
111
- server.on('error', (err) => {
112
- reject(err);
113
- });
114
- })
115
- .catch((err) => reject(err));
128
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: options.logLevel }, `Binding server to host ${portConfig.host}, port ${port}`);
129
+ server.listen({
130
+ port,
131
+ host: portConfig.host,
132
+ });
133
+ server.on('listening', () => {
134
+ resolve(port);
135
+ return unlockPort();
136
+ });
137
+ server.on('error', (err) => {
138
+ reject(err);
139
+ });
116
140
  });
117
141
  return {
142
+ type: 'started',
118
143
  port: selectedPort,
119
144
  liveEventsServer,
120
145
  close: async () => {
@@ -0,0 +1,5 @@
1
+ export type RemotionConfigResponse = {
2
+ isRemotion: true;
3
+ cwd: string;
4
+ version: string | null;
5
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/routes.js CHANGED
@@ -60,6 +60,19 @@ const output404 = (response) => {
60
60
  response.end('The outputs/ prefix has been changed, this URL is no longer valid.');
61
61
  return Promise.resolve();
62
62
  };
63
+ const handleRemotionConfig = (response, remotionRoot) => {
64
+ var _a;
65
+ response.writeHead(200, {
66
+ 'Content-Type': 'application/json',
67
+ });
68
+ const body = {
69
+ isRemotion: true,
70
+ cwd: remotionRoot,
71
+ version: (_a = process.env.REMOTION_VERSION) !== null && _a !== void 0 ? _a : null,
72
+ };
73
+ response.end(JSON.stringify(body));
74
+ return Promise.resolve();
75
+ };
63
76
  const handleFallback = async ({ remotionRoot, hash, response, getCurrentInputProps, getEnvVariables, publicDir, getRenderQueue, getRenderDefaults, numberOfAudioTags, audioLatencyHint, gitSource, logLevel, enableCrossSiteIsolation, }) => {
64
77
  const [edit] = await editorGuess;
65
78
  const displayName = (0, open_in_editor_1.getDisplayNameForEditor)(edit ? edit.command : null);
@@ -265,6 +278,9 @@ const handleRoutes = ({ staticHash, staticHashPrefix, outputHash, outputHashPref
265
278
  if (url.pathname === studio_shared_1.SOURCE_MAP_ENDPOINT) {
266
279
  return handleWasm(request, response);
267
280
  }
281
+ if (url.pathname === '/__remotion_config') {
282
+ return handleRemotionConfig(response, remotionRoot);
283
+ }
268
284
  if (url.pathname === '/events') {
269
285
  return liveEventsServer.router(request, response);
270
286
  }
@@ -2,7 +2,12 @@ import type { WebpackOverrideFn } from '@remotion/bundler';
2
2
  import type { LogLevel } from '@remotion/renderer';
3
3
  import type { GitSource, RenderDefaults, RenderJob } from '@remotion/studio-shared';
4
4
  import type { QueueMethods } from './preview-server/api-types';
5
- export declare const startStudio: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, }: {
5
+ export type StartStudioResult = {
6
+ type: 'restarted';
7
+ } | {
8
+ type: 'already-running';
9
+ };
10
+ export declare const startStudio: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, forceNew, }: {
6
11
  browserArgs: string;
7
12
  browserFlag: string;
8
13
  logLevel: LogLevel;
@@ -31,4 +36,5 @@ export declare const startStudio: ({ browserArgs, browserFlag, configValueShould
31
36
  binariesDirectory: string | null;
32
37
  forceIPv4: boolean;
33
38
  askAIEnabled: boolean;
34
- }) => Promise<void>;
39
+ forceNew: boolean;
40
+ }) => Promise<StartStudioResult>;
@@ -8,8 +8,8 @@ const renderer_1 = require("@remotion/renderer");
8
8
  const node_crypto_1 = __importDefault(require("node:crypto"));
9
9
  const node_fs_1 = require("node:fs");
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
- const better_opn_1 = require("./better-opn");
12
11
  const get_network_address_1 = require("./get-network-address");
12
+ const maybe_open_browser_1 = require("./maybe-open-browser");
13
13
  const close_and_restart_1 = require("./preview-server/close-and-restart");
14
14
  const get_absolute_public_dir_1 = require("./preview-server/get-absolute-public-dir");
15
15
  const live_events_1 = require("./preview-server/live-events");
@@ -17,26 +17,7 @@ const public_folder_1 = require("./preview-server/public-folder");
17
17
  const start_server_1 = require("./preview-server/start-server");
18
18
  const server_ready_1 = require("./server-ready");
19
19
  const watch_root_file_1 = require("./watch-root-file");
20
- const getShouldOpenBrowser = ({ configValueShouldOpenBrowser, parsedCliOpen, }) => {
21
- var _a;
22
- if (parsedCliOpen === false) {
23
- return {
24
- shouldOpenBrowser: false,
25
- reasonForBrowserDecision: '--no-open specified',
26
- };
27
- }
28
- if (((_a = process.env.BROWSER) !== null && _a !== void 0 ? _a : '').toLowerCase() === 'none') {
29
- return {
30
- shouldOpenBrowser: false,
31
- reasonForBrowserDecision: 'env BROWSER=none was set',
32
- };
33
- }
34
- if (configValueShouldOpenBrowser === false) {
35
- return { shouldOpenBrowser: false, reasonForBrowserDecision: 'Config file' };
36
- }
37
- return { shouldOpenBrowser: true, reasonForBrowserDecision: 'default' };
38
- };
39
- const startStudio = async ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, }) => {
20
+ const startStudio = async ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, experimentalClientSideRenderingEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, audioLatencyHint, enableCrossSiteIsolation, askAIEnabled, forceNew, }) => {
40
21
  try {
41
22
  if (typeof Bun === 'undefined') {
42
23
  process.title = 'node (npx remotion studio)';
@@ -78,7 +59,7 @@ const startStudio = async ({ browserArgs, browserFlag, configValueShouldOpenBrow
78
59
  },
79
60
  staticHash,
80
61
  });
81
- const { port, liveEventsServer, close } = await (0, start_server_1.startServer)({
62
+ const result = await (0, start_server_1.startServer)({
82
63
  entry: node_path_1.default.resolve(previewEntry),
83
64
  userDefinedComponent: fullEntryPath,
84
65
  getCurrentInputProps,
@@ -107,7 +88,24 @@ const startStudio = async ({ browserArgs, browserFlag, configValueShouldOpenBrow
107
88
  audioLatencyHint,
108
89
  enableCrossSiteIsolation,
109
90
  askAIEnabled,
91
+ forceNew,
110
92
  });
93
+ if (result.type === 'already-running') {
94
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `Already running on port ${result.port}.`);
95
+ const res = await (0, maybe_open_browser_1.maybeOpenBrowser)({
96
+ browserArgs,
97
+ browserFlag,
98
+ configValueShouldOpenBrowser,
99
+ parsedCliOpen,
100
+ url: `http://localhost:${result.port}`,
101
+ logLevel,
102
+ });
103
+ if (res.didOpenBrowser) {
104
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Opened browser. Pass --force-new to force a new instance.');
105
+ }
106
+ return { type: 'already-running' };
107
+ }
108
+ const { port, liveEventsServer, close } = result;
111
109
  const cleanupLiveEventsListener = (0, live_events_1.setLiveEventsListener)(liveEventsServer);
112
110
  const networkAddress = (0, get_network_address_1.getNetworkAddress)();
113
111
  if (networkAddress) {
@@ -118,25 +116,20 @@ const startStudio = async ({ browserArgs, browserFlag, configValueShouldOpenBrow
118
116
  }
119
117
  (0, server_ready_1.printServerReadyComment)('Server ready', logLevel);
120
118
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Building...');
121
- const { reasonForBrowserDecision, shouldOpenBrowser } = getShouldOpenBrowser({
119
+ await (0, maybe_open_browser_1.maybeOpenBrowser)({
120
+ browserArgs,
121
+ browserFlag,
122
122
  configValueShouldOpenBrowser,
123
123
  parsedCliOpen,
124
+ url: `http://localhost:${port}`,
125
+ logLevel,
124
126
  });
125
- if (shouldOpenBrowser) {
126
- await (0, better_opn_1.openBrowser)({
127
- url: `http://localhost:${port}`,
128
- browserArgs,
129
- browserFlag,
130
- });
131
- }
132
- else {
133
- renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `Not opening browser, reason: ${reasonForBrowserDecision}`);
134
- }
135
127
  await (0, close_and_restart_1.noOpUntilRestart)();
136
128
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Closing server to restart...');
137
129
  await liveEventsServer.closeConnections();
138
130
  cleanupLiveEventsListener();
139
131
  await close();
140
132
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue('Restarting server...'));
133
+ return { type: 'restarted' };
141
134
  };
142
135
  exports.startStudio = startStudio;
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.419",
6
+ "version": "4.0.421",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -25,11 +25,11 @@
25
25
  "dependencies": {
26
26
  "@babel/parser": "7.24.1",
27
27
  "semver": "7.5.3",
28
- "remotion": "4.0.419",
28
+ "remotion": "4.0.421",
29
29
  "recast": "0.23.11",
30
- "@remotion/bundler": "4.0.419",
31
- "@remotion/renderer": "4.0.419",
32
- "@remotion/studio-shared": "4.0.419",
30
+ "@remotion/bundler": "4.0.421",
31
+ "@remotion/renderer": "4.0.421",
32
+ "@remotion/studio-shared": "4.0.421",
33
33
  "memfs": "3.4.3",
34
34
  "source-map": "0.7.3",
35
35
  "open": "^8.4.2"
@@ -39,7 +39,7 @@
39
39
  "react": "19.2.3",
40
40
  "@babel/types": "7.24.0",
41
41
  "@types/semver": "^7.3.4",
42
- "@remotion/eslint-config-internal": "4.0.419",
42
+ "@remotion/eslint-config-internal": "4.0.421",
43
43
  "eslint": "9.19.0",
44
44
  "@types/node": "20.12.14"
45
45
  },