@remotion/studio-server 4.0.442 → 4.0.443

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,4 @@
1
+ import type { SequenceNodePath } from '@remotion/studio-shared';
2
+ export declare const getCachedNodePath: (fileName: string, line: number, column: number) => SequenceNodePath | undefined;
3
+ export declare const setCachedNodePath: (fileName: string, line: number, column: number, nodePath: SequenceNodePath) => void;
4
+ export declare const clearNodePathCache: () => void;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clearNodePathCache = exports.setCachedNodePath = exports.getCachedNodePath = void 0;
4
+ const makeCacheKey = (fileName, line, column) => {
5
+ return `${fileName}:${line}:${column}`;
6
+ };
7
+ const cache = new Map();
8
+ const getCachedNodePath = (fileName, line, column) => {
9
+ return cache.get(makeCacheKey(fileName, line, column));
10
+ };
11
+ exports.getCachedNodePath = getCachedNodePath;
12
+ const setCachedNodePath = (fileName, line, column, nodePath) => {
13
+ cache.set(makeCacheKey(fileName, line, column), nodePath);
14
+ };
15
+ exports.setCachedNodePath = setCachedNodePath;
16
+ const clearNodePathCache = () => {
17
+ cache.clear();
18
+ };
19
+ exports.clearNodePathCache = clearNodePathCache;
@@ -2,10 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.subscribeToSequenceProps = void 0;
4
4
  const sequence_props_watchers_1 = require("../sequence-props-watchers");
5
- const subscribeToSequenceProps = ({ input: { fileName, line, keys, clientId }, remotionRoot }) => {
5
+ const subscribeToSequenceProps = ({ input: { fileName, line, column, keys, clientId }, remotionRoot }) => {
6
6
  const result = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
7
7
  fileName,
8
8
  line,
9
+ column,
9
10
  keys,
10
11
  remotionRoot,
11
12
  clientId,
@@ -1,7 +1,8 @@
1
1
  import type { CanUpdateSequencePropsResponse, SequenceNodePath } from '@remotion/studio-shared';
2
- export declare const subscribeToSequencePropsWatchers: ({ fileName, line, keys, remotionRoot, clientId, }: {
2
+ export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, keys, remotionRoot, clientId, }: {
3
3
  fileName: string;
4
4
  line: number;
5
+ column: number;
5
6
  keys: string[];
6
7
  remotionRoot: string;
7
8
  clientId: string;
@@ -7,29 +7,57 @@ exports.unsubscribeClientSequencePropsWatchers = exports.unsubscribeFromSequence
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const file_watcher_1 = require("../file-watcher");
9
9
  const live_events_1 = require("./live-events");
10
+ const node_path_cache_1 = require("./node-path-cache");
10
11
  const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
11
12
  const sequencePropsWatchers = {};
12
13
  const makeWatcherKey = ({ absolutePath, nodePath, }) => {
13
14
  return `${absolutePath}:${JSON.stringify(nodePath)}`;
14
15
  };
15
- const subscribeToSequencePropsWatchers = ({ fileName, line, keys, remotionRoot, clientId, }) => {
16
+ const subscribeToSequencePropsWatchers = ({ fileName, line, column, keys, remotionRoot, clientId, }) => {
16
17
  var _a;
17
18
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
18
- // Initial lookup by line+column to resolve the nodePath
19
- const initialResult = (0, can_update_sequence_props_1.computeSequencePropsStatusByLine)({
20
- fileName,
21
- line,
22
- keys,
23
- remotionRoot,
24
- });
19
+ // Try cached nodePath first (handles stale source maps after suppressed rebuilds)
20
+ const cachedNodePath = (0, node_path_cache_1.getCachedNodePath)(fileName, line, column);
21
+ let initialResult;
22
+ if (cachedNodePath) {
23
+ const cachedResult = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
24
+ fileName,
25
+ nodePath: cachedNodePath,
26
+ keys,
27
+ remotionRoot,
28
+ });
29
+ if (cachedResult.canUpdate) {
30
+ initialResult = cachedResult;
31
+ }
32
+ else {
33
+ // Cached nodePath no longer valid, fall back to line-based lookup
34
+ initialResult = (0, can_update_sequence_props_1.computeSequencePropsStatusByLine)({
35
+ fileName,
36
+ line,
37
+ keys,
38
+ remotionRoot,
39
+ });
40
+ }
41
+ }
42
+ else {
43
+ initialResult = (0, can_update_sequence_props_1.computeSequencePropsStatusByLine)({
44
+ fileName,
45
+ line,
46
+ keys,
47
+ remotionRoot,
48
+ });
49
+ }
25
50
  if (!initialResult.canUpdate) {
26
51
  return initialResult;
27
52
  }
53
+ // Cache the resolved nodePath for future lookups with stale source maps
54
+ (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath);
28
55
  const { nodePath } = initialResult;
29
56
  const watcherKey = makeWatcherKey({ absolutePath, nodePath });
30
- // Unwatch any existing watcher for the same key
57
+ // If a watcher already exists for this key, just bump the ref count
31
58
  if ((_a = sequencePropsWatchers[clientId]) === null || _a === void 0 ? void 0 : _a[watcherKey]) {
32
- sequencePropsWatchers[clientId][watcherKey].unwatch();
59
+ sequencePropsWatchers[clientId][watcherKey].refCount++;
60
+ return initialResult;
33
61
  }
34
62
  const { unwatch } = (0, file_watcher_1.installFileWatcher)({
35
63
  file: absolutePath,
@@ -37,7 +65,13 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, keys, remotionRoot,
37
65
  if (event.type === 'deleted') {
38
66
  return;
39
67
  }
40
- const result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)(event.content, nodePath, keys);
68
+ let result;
69
+ try {
70
+ result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)(event.content, nodePath, keys);
71
+ }
72
+ catch (_a) {
73
+ return;
74
+ }
41
75
  (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
42
76
  listener.sendEventToClientId(clientId, {
43
77
  type: 'sequence-props-updated',
@@ -51,7 +85,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, keys, remotionRoot,
51
85
  if (!sequencePropsWatchers[clientId]) {
52
86
  sequencePropsWatchers[clientId] = {};
53
87
  }
54
- sequencePropsWatchers[clientId][watcherKey] = { unwatch };
88
+ sequencePropsWatchers[clientId][watcherKey] = { unwatch, refCount: 1 };
55
89
  return initialResult;
56
90
  };
57
91
  exports.subscribeToSequencePropsWatchers = subscribeToSequencePropsWatchers;
@@ -60,12 +94,13 @@ const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot
60
94
  const watcherKey = makeWatcherKey({ absolutePath, nodePath });
61
95
  if (!sequencePropsWatchers[clientId] ||
62
96
  !sequencePropsWatchers[clientId][watcherKey]) {
63
- // eslint-disable-next-line no-console
64
- console.warn(`Unexpected: unsubscribe for sequence props watcher that does not exist (clientId=${clientId}, key=${watcherKey})`);
65
97
  return;
66
98
  }
67
- sequencePropsWatchers[clientId][watcherKey].unwatch();
68
- delete sequencePropsWatchers[clientId][watcherKey];
99
+ sequencePropsWatchers[clientId][watcherKey].refCount--;
100
+ if (sequencePropsWatchers[clientId][watcherKey].refCount <= 0) {
101
+ sequencePropsWatchers[clientId][watcherKey].unwatch();
102
+ delete sequencePropsWatchers[clientId][watcherKey];
103
+ }
69
104
  };
70
105
  exports.unsubscribeFromSequencePropsWatchers = unsubscribeFromSequencePropsWatchers;
71
106
  const unsubscribeClientSequencePropsWatchers = (clientId) => {
@@ -12,6 +12,7 @@ const routes_1 = require("../routes");
12
12
  const dev_middleware_1 = require("./dev-middleware");
13
13
  const hot_middleware_1 = require("./hot-middleware");
14
14
  const live_events_1 = require("./live-events");
15
+ const node_path_cache_1 = require("./node-path-cache");
15
16
  const undo_stack_1 = require("./undo-stack");
16
17
  const watch_ignore_next_change_1 = require("./watch-ignore-next-change");
17
18
  const startServer = async (options) => {
@@ -67,6 +68,9 @@ const startServer = async (options) => {
67
68
  };
68
69
  });
69
70
  (0, hot_middleware_1.setupWebpackHmr)(compiler, options.logLevel, liveEventsServer);
71
+ compiler.hooks.done.tap('remotion-node-path-cache', () => {
72
+ (0, node_path_cache_1.clearNodePathCache)();
73
+ });
70
74
  const server = node_http_1.default.createServer((request, response) => {
71
75
  if (options.enableCrossSiteIsolation) {
72
76
  response.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
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.442",
6
+ "version": "4.0.443",
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.442",
30
+ "remotion": "4.0.443",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.442",
33
- "@remotion/renderer": "4.0.442",
34
- "@remotion/studio-shared": "4.0.442",
32
+ "@remotion/bundler": "4.0.443",
33
+ "@remotion/renderer": "4.0.443",
34
+ "@remotion/studio-shared": "4.0.443",
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.442",
44
+ "@remotion/eslint-config-internal": "4.0.443",
45
45
  "eslint": "9.19.0",
46
46
  "@types/node": "20.12.14",
47
47
  "@typescript/native-preview": "7.0.0-dev.20260217.1"