@remotion/studio-server 4.0.439 → 4.0.440

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.
@@ -3,8 +3,8 @@
3
3
  * https://github.com/webpack-contrib/webpack-hot-middleware#readme
4
4
  * and rewritten in TypeScript. This file is MIT licensed
5
5
  */
6
- import type { IncomingMessage, ServerResponse } from 'node:http';
7
6
  import type { webpack } from '@remotion/bundler';
7
+ import type { LiveEventsServer } from '../live-events';
8
8
  declare global {
9
9
  const __webpack_hash__: unknown;
10
10
  interface HotNotifierInfo {
@@ -99,4 +99,4 @@ declare global {
99
99
  };
100
100
  type ModuleId = string | number;
101
101
  }
102
- export declare const webpackHotMiddleware: (compiler: webpack.Compiler, logLevel: "error" | "info" | "trace" | "verbose" | "warn") => (req: IncomingMessage, res: ServerResponse<IncomingMessage>, next: () => void) => void;
102
+ export declare const setupWebpackHmr: (compiler: webpack.Compiler, logLevel: "error" | "info" | "trace" | "verbose" | "warn", liveEventsServer: LiveEventsServer) => void;
@@ -5,99 +5,35 @@
5
5
  * and rewritten in TypeScript. This file is MIT licensed
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.webpackHotMiddleware = void 0;
9
- const node_url_1 = require("node:url");
8
+ exports.setupWebpackHmr = void 0;
10
9
  const renderer_1 = require("@remotion/renderer");
11
- const studio_shared_1 = require("@remotion/studio-shared");
12
- const pathMatch = function (url, path) {
13
- try {
14
- return (0, node_url_1.parse)(url).pathname === path;
15
- }
16
- catch (_a) {
17
- return false;
18
- }
19
- };
20
- const webpackHotMiddleware = (compiler, logLevel) => {
21
- const eventStream = createEventStream(studio_shared_1.hotMiddlewareOptions.heartbeat);
10
+ const setupWebpackHmr = (compiler, logLevel, liveEventsServer) => {
22
11
  let latestStats = null;
12
+ const publishHmr = (hmrEvent) => {
13
+ liveEventsServer.sendEventToClient({ type: 'hmr', hmrEvent });
14
+ };
23
15
  compiler.hooks.invalid.tap('remotion', onInvalid);
24
16
  compiler.hooks.done.tap('remotion', onDone);
25
17
  function onInvalid() {
26
18
  latestStats = null;
27
19
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Building...');
28
- eventStream === null || eventStream === void 0 ? void 0 : eventStream.publish({
20
+ publishHmr({
29
21
  action: 'building',
30
22
  });
31
23
  }
32
24
  function onDone(statsResult) {
33
25
  // Keep hold of latest stats so they can be propagated to new clients
34
26
  latestStats = statsResult;
35
- publishStats('built', latestStats, eventStream);
27
+ publishStats('built', latestStats, publishHmr);
36
28
  }
37
- const middleware = function (req, res, next) {
38
- if (!pathMatch(req.url, studio_shared_1.hotMiddlewareOptions.path))
39
- return next();
40
- eventStream === null || eventStream === void 0 ? void 0 : eventStream.handler(req, res);
29
+ liveEventsServer.addNewClientListener(() => {
41
30
  if (latestStats) {
42
- publishStats('sync', latestStats, eventStream);
31
+ publishStats('sync', latestStats, publishHmr);
43
32
  }
44
- };
45
- return middleware;
33
+ });
46
34
  };
47
- exports.webpackHotMiddleware = webpackHotMiddleware;
48
- function createEventStream(heartbeat) {
49
- let clientId = 0;
50
- let clients = {};
51
- function everyClient(fn) {
52
- Object.keys(clients).forEach((id) => {
53
- fn(clients[id]);
54
- });
55
- }
56
- const interval = setInterval(() => {
57
- everyClient((client) => {
58
- client.write('data: \uD83D\uDC93\n\n');
59
- });
60
- }, heartbeat).unref();
61
- return {
62
- close() {
63
- clearInterval(interval);
64
- everyClient((client) => {
65
- if (!client.finished)
66
- client.end();
67
- });
68
- clients = {};
69
- },
70
- handler(req, res) {
71
- const headers = {
72
- 'Access-Control-Allow-Origin': '*',
73
- 'Content-Type': 'text/event-stream;charset=utf-8',
74
- 'Cache-Control': 'no-cache, no-transform',
75
- };
76
- const isHttp1 = !(parseInt(req.httpVersion, 10) >= 2);
77
- if (isHttp1) {
78
- req.socket.setKeepAlive(true);
79
- Object.assign(headers, {
80
- Connection: 'keep-alive',
81
- });
82
- }
83
- res.writeHead(200, headers);
84
- res.write('\n');
85
- const id = clientId++;
86
- clients[id] = res;
87
- req.on('close', () => {
88
- if (!res.finished)
89
- res.end();
90
- delete clients[id];
91
- });
92
- },
93
- publish(payload) {
94
- everyClient((client) => {
95
- client.write('data: ' + JSON.stringify(payload) + '\n\n');
96
- });
97
- },
98
- };
99
- }
100
- function publishStats(action, statsResult, eventStream) {
35
+ exports.setupWebpackHmr = setupWebpackHmr;
36
+ function publishStats(action, statsResult, publishHmr) {
101
37
  const stats = statsResult.toJson({
102
38
  all: false,
103
39
  cached: true,
@@ -114,7 +50,7 @@ function publishStats(action, statsResult, eventStream) {
114
50
  if (bundles.length === 1 && !name && statsResult.compilation) {
115
51
  name = statsResult.compilation.name || '';
116
52
  }
117
- eventStream === null || eventStream === void 0 ? void 0 : eventStream.publish({
53
+ publishHmr({
118
54
  name,
119
55
  action,
120
56
  time: _stats.time,
@@ -5,6 +5,7 @@ export type LiveEventsServer = {
5
5
  sendEventToClientId: (clientId: string, event: EventSourceEvent) => void;
6
6
  router: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
7
7
  closeConnections: () => Promise<void>;
8
+ addNewClientListener: (cb: () => void) => () => void;
8
9
  };
9
10
  export type InitialUndoRedoState = {
10
11
  undoFile: string | null;
@@ -11,6 +11,7 @@ const serializeMessage = (message) => {
11
11
  let printPortMessageTimeout = null;
12
12
  const makeLiveEventsRouter = (logLevel, getInitialUndoRedoState) => {
13
13
  let clients = [];
14
+ let newClientListeners = [];
14
15
  const router = (request, response) => {
15
16
  const headers = {
16
17
  'content-type': 'text/event-stream;charset=utf-8',
@@ -31,6 +32,7 @@ const makeLiveEventsRouter = (logLevel, getInitialUndoRedoState) => {
31
32
  response,
32
33
  };
33
34
  clients.push(newClient);
35
+ newClientListeners.forEach((cb) => cb());
34
36
  if (printPortMessageTimeout) {
35
37
  clearTimeout(printPortMessageTimeout);
36
38
  }
@@ -62,10 +64,17 @@ const makeLiveEventsRouter = (logLevel, getInitialUndoRedoState) => {
62
64
  client.response.write(serializeMessage(event));
63
65
  }
64
66
  };
67
+ const addNewClientListener = (cb) => {
68
+ newClientListeners.push(cb);
69
+ return () => {
70
+ newClientListeners = newClientListeners.filter((l) => l !== cb);
71
+ };
72
+ };
65
73
  return {
66
74
  sendEventToClient,
67
75
  sendEventToClientId,
68
76
  router,
77
+ addNewClientListener,
69
78
  closeConnections: () => {
70
79
  return Promise.all(clients.map((client) => {
71
80
  return new Promise((resolve) => {
@@ -58,7 +58,6 @@ const startServer = async (options) => {
58
58
  }
59
59
  (0, watch_ignore_next_change_1.setWatchIgnoreNextChangePlugin)(watchIgnorePlugin);
60
60
  const wdmMiddleware = (0, dev_middleware_1.wdm)(compiler, options.logLevel);
61
- const whm = (0, hot_middleware_1.webpackHotMiddleware)(compiler, options.logLevel);
62
61
  const liveEventsServer = (0, live_events_1.makeLiveEventsRouter)(options.logLevel, () => {
63
62
  const undoStack = (0, undo_stack_1.getUndoStack)();
64
63
  const redoStack = (0, undo_stack_1.getRedoStack)();
@@ -67,6 +66,7 @@ const startServer = async (options) => {
67
66
  redoFile: redoStack.length > 0 ? redoStack[redoStack.length - 1].filePath : null,
68
67
  };
69
68
  });
69
+ (0, hot_middleware_1.setupWebpackHmr)(compiler, options.logLevel, liveEventsServer);
70
70
  const server = node_http_1.default.createServer((request, response) => {
71
71
  if (options.enableCrossSiteIsolation) {
72
72
  response.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@@ -76,13 +76,6 @@ const startServer = async (options) => {
76
76
  wdmMiddleware(request, response, () => {
77
77
  resolve();
78
78
  });
79
- })
80
- .then(() => {
81
- return new Promise((resolve) => {
82
- whm(request, response, () => {
83
- resolve();
84
- });
85
- });
86
79
  })
87
80
  .then(() => {
88
81
  return (0, routes_1.handleRoutes)({
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.439",
6
+ "version": "4.0.440",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -27,11 +27,11 @@
27
27
  "@babel/parser": "7.24.1",
28
28
  "semver": "7.5.3",
29
29
  "prettier": "3.8.1",
30
- "remotion": "4.0.439",
30
+ "remotion": "4.0.440",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.439",
33
- "@remotion/renderer": "4.0.439",
34
- "@remotion/studio-shared": "4.0.439",
32
+ "@remotion/bundler": "4.0.440",
33
+ "@remotion/renderer": "4.0.440",
34
+ "@remotion/studio-shared": "4.0.440",
35
35
  "memfs": "3.4.3",
36
36
  "source-map": "0.7.3",
37
37
  "open": "^8.4.2"
@@ -41,7 +41,7 @@
41
41
  "react": "19.2.3",
42
42
  "@babel/types": "7.24.0",
43
43
  "@types/semver": "^7.3.4",
44
- "@remotion/eslint-config-internal": "4.0.439",
44
+ "@remotion/eslint-config-internal": "4.0.440",
45
45
  "eslint": "9.19.0",
46
46
  "@types/node": "20.12.14",
47
47
  "@typescript/native-preview": "7.0.0-dev.20260217.1"