@remotion/studio-server 4.0.461 → 4.0.462

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 (30) hide show
  1. package/dist/codemods/update-effect-props/update-effect-props.d.ts +52 -0
  2. package/dist/codemods/update-effect-props/update-effect-props.js +229 -0
  3. package/dist/codemods/update-sequence-props/find-props-to-delete.d.ts +6 -0
  4. package/dist/codemods/update-sequence-props/find-props-to-delete.js +37 -0
  5. package/dist/codemods/update-sequence-props.d.ts +1 -1
  6. package/dist/codemods/update-sequence-props.js +11 -2
  7. package/dist/preview-server/api-routes.js +2 -0
  8. package/dist/preview-server/routes/can-update-effect-props.d.ts +20 -0
  9. package/dist/preview-server/routes/can-update-effect-props.js +146 -0
  10. package/dist/preview-server/routes/can-update-sequence-props.d.ts +21 -3
  11. package/dist/preview-server/routes/can-update-sequence-props.js +64 -13
  12. package/dist/preview-server/routes/log-update.js +21 -4
  13. package/dist/preview-server/routes/log-updates/format-effect-prop-change.d.ts +10 -0
  14. package/dist/preview-server/routes/log-updates/format-effect-prop-change.js +51 -0
  15. package/dist/preview-server/routes/log-updates/format-side-prop.d.ts +0 -0
  16. package/dist/preview-server/routes/log-updates/format-side-prop.js +1 -0
  17. package/dist/preview-server/routes/log-updates/log-effect-update.d.ts +14 -0
  18. package/dist/preview-server/routes/log-updates/log-effect-update.js +23 -0
  19. package/dist/preview-server/routes/save-effect-props.d.ts +3 -0
  20. package/dist/preview-server/routes/save-effect-props.js +107 -0
  21. package/dist/preview-server/routes/save-sequence-props.d.ts +2 -3
  22. package/dist/preview-server/routes/save-sequence-props.js +7 -7
  23. package/dist/preview-server/routes/subscribe-to-sequence-props.js +4 -3
  24. package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +4 -2
  25. package/dist/preview-server/sequence-props-watchers.d.ts +7 -3
  26. package/dist/preview-server/sequence-props-watchers.js +51 -22
  27. package/dist/preview-server/undo-stack.d.ts +3 -1
  28. package/package.json +6 -7
  29. package/dist/codemods/jsx-sequence-context.d.ts +0 -11
  30. package/dist/codemods/jsx-sequence-context.js +0 -68
@@ -36,12 +36,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findJsxElementAtNodePath = exports.extractStaticValue = exports.isStaticValue = void 0;
39
+ exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.computeSequencePropsOnlyStatus = exports.lineColumnToNodePath = exports.findJsxElementAtNodePath = exports.extractStaticValue = exports.isStaticValue = void 0;
40
40
  const node_fs_1 = require("node:fs");
41
41
  const node_path_1 = __importDefault(require("node:path"));
42
+ const renderer_1 = require("@remotion/renderer");
42
43
  const recast = __importStar(require("recast"));
43
44
  const parse_ast_1 = require("../../codemods/parse-ast");
44
45
  const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
46
+ const can_update_effect_props_1 = require("./can-update-effect-props");
45
47
  const isStaticValue = (node) => {
46
48
  switch (node.type) {
47
49
  case 'NumericLiteral':
@@ -247,12 +249,14 @@ const getNestedPropStatus = (jsxElement, parentKey, childKey) => {
247
249
  }
248
250
  return { canUpdate: true, codeValue };
249
251
  };
250
- const computeSequencePropsStatusFromContent = (fileContents, nodePath, keys) => {
251
- const ast = (0, parse_ast_1.parseAst)(fileContents);
252
- const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
253
- if (!jsxElement) {
254
- throw new Error('Could not find a JSX element at the specified location');
255
- }
252
+ const computeEffectsForJsx = ({ jsxElement, effects, }) => {
253
+ return effects.map((effect, effectIndex) => (0, can_update_effect_props_1.computeEffectPropStatus)({
254
+ jsx: jsxElement,
255
+ effectIndex,
256
+ keys: effect,
257
+ }));
258
+ };
259
+ const computeSequenceOnlyPropsRecord = ({ jsxElement, keys, }) => {
256
260
  const allProps = getPropsStatus(jsxElement);
257
261
  const filteredProps = {};
258
262
  for (const key of keys) {
@@ -267,23 +271,57 @@ const computeSequencePropsStatusFromContent = (fileContents, nodePath, keys) =>
267
271
  filteredProps[key] = { canUpdate: true, codeValue: undefined };
268
272
  }
269
273
  }
274
+ return filteredProps;
275
+ };
276
+ const computeSequencePropsOnlyStatus = ({ fileName, nodePath, keys, remotionRoot, }) => {
277
+ const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
278
+ const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
279
+ if (fileRelativeToRoot.startsWith('..')) {
280
+ throw new Error('Cannot read a file outside the project');
281
+ }
282
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
283
+ const ast = (0, parse_ast_1.parseAst)(fileContents);
284
+ const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
285
+ if (!jsxElement) {
286
+ throw new Error('Cannot compute sequence props: Could not find a JSX element at the specified location');
287
+ }
288
+ return {
289
+ canUpdate: true,
290
+ props: computeSequenceOnlyPropsRecord({ jsxElement, keys }),
291
+ };
292
+ };
293
+ exports.computeSequencePropsOnlyStatus = computeSequencePropsOnlyStatus;
294
+ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, effects, }) => {
295
+ const ast = (0, parse_ast_1.parseAst)(fileContents);
296
+ const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
297
+ if (!jsxElement) {
298
+ throw new Error('Cannot compute sequence props status: Could not find a JSX element at the specified location');
299
+ }
300
+ const filteredProps = computeSequenceOnlyPropsRecord({ jsxElement, keys });
301
+ const effectsStatuses = computeEffectsForJsx({ jsxElement, effects });
270
302
  return {
271
303
  canUpdate: true,
272
304
  props: filteredProps,
305
+ effects: effectsStatuses,
273
306
  };
274
307
  };
275
308
  exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
276
- const computeSequencePropsStatus = ({ fileName, nodePath, keys, remotionRoot, }) => {
309
+ const computeSequencePropsStatus = ({ fileName, nodePath, keys, effects, remotionRoot, }) => {
277
310
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
278
311
  const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
279
312
  if (fileRelativeToRoot.startsWith('..')) {
280
313
  throw new Error('Cannot read a file outside the project');
281
314
  }
282
315
  const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
283
- return (0, exports.computeSequencePropsStatusFromContent)(fileContents, nodePath, keys);
316
+ return (0, exports.computeSequencePropsStatusFromContent)({
317
+ fileContents,
318
+ nodePath,
319
+ keys,
320
+ effects,
321
+ });
284
322
  };
285
323
  exports.computeSequencePropsStatus = computeSequencePropsStatus;
286
- const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, remotionRoot, }) => {
324
+ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, effects, remotionRoot, logLevel, }) => {
287
325
  try {
288
326
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
289
327
  const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
@@ -294,24 +332,37 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, re
294
332
  const ast = (0, parse_ast_1.parseAst)(fileContents);
295
333
  const resolvedNodePath = (0, exports.lineColumnToNodePath)(ast, line);
296
334
  if (!resolvedNodePath) {
297
- throw new Error('Could not find a JSX element at the specified location');
335
+ return {
336
+ status: {
337
+ canUpdate: false,
338
+ reason: 'not-found',
339
+ },
340
+ success: false,
341
+ };
298
342
  }
299
343
  return {
300
344
  status: (0, exports.computeSequencePropsStatus)({
301
345
  fileName,
302
346
  nodePath: resolvedNodePath,
303
347
  keys,
348
+ effects,
304
349
  remotionRoot,
305
350
  }),
306
- nodePath: resolvedNodePath,
351
+ nodePath: {
352
+ absolutePath,
353
+ nodePath: resolvedNodePath,
354
+ sequenceKeys: keys,
355
+ effectKeys: effects,
356
+ },
307
357
  success: true,
308
358
  };
309
359
  }
310
360
  catch (err) {
361
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, err);
311
362
  return {
312
363
  status: {
313
364
  canUpdate: false,
314
- reason: err.message,
365
+ reason: 'error',
315
366
  },
316
367
  success: false,
317
368
  };
@@ -54,13 +54,30 @@ const formatSimpleProp = (key, value) => {
54
54
  const formatNestedProp = (parentKey, childKey, value) => {
55
55
  return `${attrName(parentKey)}${equals('=')}${punctuation('{{')}${punctuation(childKey)}${punctuation(':')} ${colorValue(value)}${punctuation('}}')}`;
56
56
  };
57
+ const formatPropDelta = ({ key, valueString }) => {
58
+ if (!colorEnabled()) {
59
+ const dotIdx = key.indexOf('.');
60
+ if (dotIdx === -1) {
61
+ return `${key}={${valueString}}`;
62
+ }
63
+ const parent = key.slice(0, dotIdx);
64
+ const child = key.slice(dotIdx + 1);
65
+ return `${parent}={{${child}: ${valueString}}}`;
66
+ }
67
+ const dotIdx = key.indexOf('.');
68
+ if (dotIdx === -1) {
69
+ return formatSimpleProp(key, valueString);
70
+ }
71
+ return formatNestedProp(key.slice(0, dotIdx), key.slice(dotIdx + 1), valueString);
72
+ };
57
73
  const formatSideProps = ({ removedProps, addedProps, }) => {
58
74
  const parts = [];
59
- for (const { valueString } of removedProps) {
60
- parts.push(colorEnabled() ? (0, exports.strikeThrough)(valueString) : valueString);
75
+ for (const prop of removedProps) {
76
+ const formatted = formatPropDelta(prop);
77
+ parts.push(colorEnabled() ? (0, exports.strikeThrough)(formatted) : formatted);
61
78
  }
62
- for (const { valueString } of addedProps) {
63
- parts.push(valueString);
79
+ for (const prop of addedProps) {
80
+ parts.push(formatPropDelta(prop));
64
81
  }
65
82
  if (parts.length === 0) {
66
83
  return '';
@@ -0,0 +1,10 @@
1
+ import { type PropDelta } from './formatting';
2
+ export declare const formatEffectPropChange: ({ effectName, key, oldValueString, newValueString, defaultValueString, removedProps, addedProps, }: {
3
+ effectName: string;
4
+ key: string;
5
+ oldValueString: string;
6
+ newValueString: string;
7
+ defaultValueString: string | null;
8
+ removedProps: PropDelta[];
9
+ addedProps: PropDelta[];
10
+ }) => string;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatEffectPropChange = void 0;
4
+ const format_side_props_1 = require("./format-side-props");
5
+ const formatting_1 = require("./formatting");
6
+ const formatEffectPropBody = (key, valueString) => {
7
+ return `${(0, formatting_1.punctuation)(key)}${(0, formatting_1.punctuation)(': ')}${(0, formatting_1.colorValue)(valueString)}`;
8
+ };
9
+ const formatEffectCall = (effectName, key, valueString) => {
10
+ return `${(0, formatting_1.attrName)(effectName)}${(0, formatting_1.punctuation)('(')}${(0, formatting_1.punctuation)('{')}${formatEffectPropBody(key, valueString)}${(0, formatting_1.punctuation)('}')}${(0, formatting_1.punctuation)(')')}`;
11
+ };
12
+ const formatEffectDeletion = ({ effectName, key, valueString, }) => {
13
+ const inner = formatEffectPropBody(key, valueString);
14
+ return `${(0, formatting_1.attrName)(effectName)}${(0, formatting_1.punctuation)('(')}${(0, formatting_1.punctuation)('{')}${(0, formatting_1.strikeThroughOrRemovedPrefix)(inner)}${(0, formatting_1.punctuation)('}')}${(0, formatting_1.punctuation)(')')}`;
15
+ };
16
+ const formatEffectAddition = ({ effectName, key, valueString, }) => {
17
+ return (0, formatting_1.addedPrefixIfNoColor)(formatEffectCall(effectName, key, valueString));
18
+ };
19
+ const formatEffectInnerPropChange = ({ effectName, key, oldValueString, newValueString, defaultValueString, }) => {
20
+ if (defaultValueString !== null && newValueString === defaultValueString) {
21
+ return formatEffectDeletion({
22
+ effectName,
23
+ key,
24
+ valueString: oldValueString,
25
+ });
26
+ }
27
+ if (defaultValueString !== null && oldValueString === defaultValueString) {
28
+ return formatEffectAddition({
29
+ effectName,
30
+ key,
31
+ valueString: newValueString,
32
+ });
33
+ }
34
+ return `${formatEffectCall(effectName, key, oldValueString)} \u2192 ${formatEffectCall(effectName, key, newValueString)}`;
35
+ };
36
+ const formatEffectPropChange = ({ effectName, key, oldValueString, newValueString, defaultValueString, removedProps, addedProps, }) => {
37
+ const suffix = (0, format_side_props_1.formatSideProps)({ removedProps, addedProps });
38
+ return [
39
+ formatEffectInnerPropChange({
40
+ effectName,
41
+ key,
42
+ oldValueString,
43
+ newValueString,
44
+ defaultValueString,
45
+ }),
46
+ suffix,
47
+ ]
48
+ .filter(Boolean)
49
+ .join(', ');
50
+ };
51
+ exports.formatEffectPropChange = formatEffectPropChange;
@@ -0,0 +1,14 @@
1
+ import type { PropDelta } from './formatting';
2
+ export declare const logEffectUpdate: ({ fileRelativeToRoot, line, effectName, propKey, oldValueString, newValueString, defaultValueString, formatted, logLevel, removedProps, addedProps, }: {
3
+ fileRelativeToRoot: string;
4
+ line: number;
5
+ effectName: string;
6
+ propKey: string;
7
+ oldValueString: string;
8
+ newValueString: string;
9
+ defaultValueString: string | null;
10
+ formatted: boolean;
11
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
12
+ removedProps: PropDelta[];
13
+ addedProps: PropDelta[];
14
+ }) => void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logEffectUpdate = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
5
+ const format_effect_prop_change_1 = require("./format-effect-prop-change");
6
+ const log_update_1 = require("./log-update");
7
+ const logEffectUpdate = ({ fileRelativeToRoot, line, effectName, propKey, oldValueString, newValueString, defaultValueString, formatted, logLevel, removedProps, addedProps, }) => {
8
+ const locationLabel = `${fileRelativeToRoot}:${line}`;
9
+ const propChange = (0, format_effect_prop_change_1.formatEffectPropChange)({
10
+ effectName,
11
+ key: propKey,
12
+ oldValueString: (0, log_update_1.normalizeQuotes)(oldValueString),
13
+ newValueString: (0, log_update_1.normalizeQuotes)(newValueString),
14
+ defaultValueString: defaultValueString !== null ? (0, log_update_1.normalizeQuotes)(defaultValueString) : null,
15
+ removedProps,
16
+ addedProps,
17
+ });
18
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} ${propChange}`);
19
+ if (!formatted) {
20
+ (0, log_update_1.warnAboutPrettierOnce)(logLevel);
21
+ }
22
+ };
23
+ exports.logEffectUpdate = logEffectUpdate;
@@ -0,0 +1,3 @@
1
+ import type { SaveEffectPropsRequest, SaveEffectPropsResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const saveEffectPropsHandler: ApiHandler<SaveEffectPropsRequest, SaveEffectPropsResponse>;
@@ -0,0 +1,107 @@
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.saveEffectPropsHandler = void 0;
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const renderer_1 = require("@remotion/renderer");
10
+ const studio_shared_1 = require("@remotion/studio-shared");
11
+ const parse_ast_1 = require("../../codemods/parse-ast");
12
+ const update_effect_props_1 = require("../../codemods/update-effect-props/update-effect-props");
13
+ const file_watcher_1 = require("../../file-watcher");
14
+ const undo_stack_1 = require("../undo-stack");
15
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
16
+ const can_update_effect_props_1 = require("./can-update-effect-props");
17
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
18
+ const format_effect_prop_change_1 = require("./log-updates/format-effect-prop-change");
19
+ const log_effect_update_1 = require("./log-updates/log-effect-update");
20
+ const log_update_1 = require("./log-updates/log-update");
21
+ const saveEffectPropsHandler = async ({ input: { fileName, sequenceNodePath, effectIndex, key, value, defaultValue, schema, }, remotionRoot, logLevel, }) => {
22
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-effect-props] Received request for fileName="${fileName}" effectIndex=${effectIndex} key="${key}"`);
23
+ const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
24
+ const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
25
+ if (fileRelativeToRoot.startsWith('..')) {
26
+ throw new Error('Cannot modify a file outside the project');
27
+ }
28
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
29
+ const parsedDefault = defaultValue !== null ? JSON.parse(defaultValue) : null;
30
+ const { output, oldValueString, formatted, logLine, effectCallee } = await (0, update_effect_props_1.updateEffectProps)({
31
+ input: fileContents,
32
+ sequenceNodePath: sequenceNodePath.nodePath,
33
+ effectIndex,
34
+ update: {
35
+ key,
36
+ value: JSON.parse(value),
37
+ defaultValue: parsedDefault,
38
+ },
39
+ });
40
+ const defaultValueString = parsedDefault !== null ? JSON.stringify(parsedDefault) : null;
41
+ const normalizedOld = (0, log_update_1.normalizeQuotes)(oldValueString);
42
+ const normalizedNew = (0, log_update_1.normalizeQuotes)(value);
43
+ const normalizedDefault = defaultValueString !== null ? (0, log_update_1.normalizeQuotes)(defaultValueString) : null;
44
+ const undoPropChange = (0, format_effect_prop_change_1.formatEffectPropChange)({
45
+ effectName: effectCallee,
46
+ key,
47
+ oldValueString: normalizedNew,
48
+ newValueString: normalizedOld,
49
+ defaultValueString: normalizedDefault,
50
+ removedProps: [],
51
+ addedProps: [],
52
+ });
53
+ const redoPropChange = (0, format_effect_prop_change_1.formatEffectPropChange)({
54
+ effectName: effectCallee,
55
+ key,
56
+ oldValueString: normalizedOld,
57
+ newValueString: normalizedNew,
58
+ defaultValueString: normalizedDefault,
59
+ removedProps: [],
60
+ addedProps: [],
61
+ });
62
+ (0, undo_stack_1.pushToUndoStack)({
63
+ filePath: absolutePath,
64
+ oldContents: fileContents,
65
+ logLevel,
66
+ remotionRoot,
67
+ logLine,
68
+ description: {
69
+ undoMessage: `↩️ ${undoPropChange}`,
70
+ redoMessage: `↪️ ${redoPropChange}`,
71
+ },
72
+ entryType: 'effect-props',
73
+ suppressHmrOnFileRestore: true,
74
+ });
75
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
76
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
77
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output);
78
+ (0, log_effect_update_1.logEffectUpdate)({
79
+ fileRelativeToRoot,
80
+ line: logLine,
81
+ effectName: effectCallee,
82
+ propKey: key,
83
+ oldValueString,
84
+ newValueString: value,
85
+ defaultValueString,
86
+ formatted,
87
+ logLevel,
88
+ removedProps: [],
89
+ addedProps: [],
90
+ });
91
+ (0, undo_stack_1.printUndoHint)(logLevel);
92
+ const ast = (0, parse_ast_1.parseAst)((0, node_fs_1.readFileSync)(absolutePath, 'utf-8'));
93
+ const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath.nodePath);
94
+ if (!jsx) {
95
+ return {
96
+ canUpdate: false,
97
+ effectIndex,
98
+ reason: 'not-found',
99
+ };
100
+ }
101
+ return (0, can_update_effect_props_1.computeEffectPropStatus)({
102
+ jsx,
103
+ effectIndex,
104
+ keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
105
+ });
106
+ };
107
+ exports.saveEffectPropsHandler = saveEffectPropsHandler;
@@ -1,4 +1,3 @@
1
- import type { SaveSequencePropsRequest } from '@remotion/studio-shared';
2
- import type { CanUpdateSequencePropsResponse } from 'remotion';
1
+ import type { SaveSequencePropsRequest, SaveSequencePropsResponse } from '@remotion/studio-shared';
3
2
  import type { ApiHandler } from '../api-types';
4
- export declare const saveSequencePropsHandler: ApiHandler<SaveSequencePropsRequest, CanUpdateSequencePropsResponse>;
3
+ export declare const saveSequencePropsHandler: ApiHandler<SaveSequencePropsRequest, SaveSequencePropsResponse>;
@@ -7,8 +7,8 @@ exports.saveSequencePropsHandler = void 0;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const renderer_1 = require("@remotion/renderer");
10
- const remotion_1 = require("remotion");
11
- const get_all_schema_keys_1 = require("../../codemods/get-all-schema-keys");
10
+ const studio_shared_1 = require("@remotion/studio-shared");
11
+ const no_react_1 = require("remotion/no-react");
12
12
  const update_sequence_props_1 = require("../../codemods/update-sequence-props/update-sequence-props");
13
13
  const file_watcher_1 = require("../../file-watcher");
14
14
  const undo_stack_1 = require("../undo-stack");
@@ -26,7 +26,7 @@ const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, valu
26
26
  const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
27
27
  const { output, oldValueStrings, formatted, logLine, removedProps } = await (0, update_sequence_props_1.updateSequenceProps)({
28
28
  input: fileContents,
29
- nodePath,
29
+ nodePath: nodePath.nodePath,
30
30
  updates: [
31
31
  {
32
32
  key,
@@ -34,7 +34,7 @@ const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, valu
34
34
  defaultValue: defaultValue !== null ? JSON.parse(defaultValue) : null,
35
35
  },
36
36
  ],
37
- schema: remotion_1.Internals.sequenceSchema,
37
+ schema: no_react_1.NoReactInternals.sequenceSchema,
38
38
  });
39
39
  const oldValueString = oldValueStrings[0];
40
40
  const newValueString = JSON.stringify(JSON.parse(value));
@@ -88,10 +88,10 @@ const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, valu
88
88
  addedProps: [],
89
89
  });
90
90
  (0, undo_stack_1.printUndoHint)(logLevel);
91
- const newStatus = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
91
+ const newStatus = (0, can_update_sequence_props_1.computeSequencePropsOnlyStatus)({
92
92
  fileName,
93
- keys: (0, get_all_schema_keys_1.getAllSchemaKeys)(schema),
94
- nodePath,
93
+ keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
94
+ nodePath: nodePath.nodePath,
95
95
  remotionRoot,
96
96
  });
97
97
  return newStatus;
@@ -1,16 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.subscribeToSequenceProps = void 0;
4
- const get_all_schema_keys_1 = require("../../codemods/get-all-schema-keys");
5
4
  const sequence_props_watchers_1 = require("../sequence-props-watchers");
6
- const subscribeToSequenceProps = ({ input: { fileName, line, column, schema, clientId }, remotionRoot }) => {
5
+ const subscribeToSequenceProps = ({ input: { fileName, line, column, keys, effects, clientId }, remotionRoot, logLevel, }) => {
7
6
  const result = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
8
7
  fileName,
9
8
  line,
10
9
  column,
11
- keys: (0, get_all_schema_keys_1.getAllSchemaKeys)(schema),
10
+ keys,
11
+ effects,
12
12
  remotionRoot,
13
13
  clientId,
14
+ logLevel,
14
15
  });
15
16
  return Promise.resolve(result);
16
17
  };
@@ -2,12 +2,14 @@
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 }, remotionRoot }) => {
5
+ const unsubscribeFromSequenceProps = ({ input: { fileName, nodePath, clientId, sequenceKeys, effectKeys }, remotionRoot, }) => {
6
6
  (0, sequence_props_watchers_1.unsubscribeFromSequencePropsWatchers)({
7
7
  fileName,
8
- nodePath,
8
+ nodePath: nodePath.nodePath,
9
9
  remotionRoot,
10
10
  clientId,
11
+ sequenceKeys,
12
+ effectKeys,
11
13
  });
12
14
  return Promise.resolve(undefined);
13
15
  };
@@ -1,17 +1,21 @@
1
- import type { SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
1
+ import { type SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
2
2
  import type { SequenceNodePath } from 'remotion';
3
- export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, keys, remotionRoot, clientId, }: {
3
+ export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, keys, effects, remotionRoot, clientId, logLevel, }: {
4
4
  fileName: string;
5
5
  line: number;
6
6
  column: number;
7
7
  keys: string[];
8
+ effects: string[][];
8
9
  remotionRoot: string;
9
10
  clientId: string;
11
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
10
12
  }) => SubscribeToSequencePropsResponse;
11
- export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, }: {
13
+ export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, }: {
12
14
  fileName: string;
13
15
  nodePath: SequenceNodePath;
14
16
  remotionRoot: string;
15
17
  clientId: string;
18
+ sequenceKeys: string[];
19
+ effectKeys: string[][];
16
20
  }) => void;
17
21
  export declare const unsubscribeClientSequencePropsWatchers: (clientId: string) => void;
@@ -5,15 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.unsubscribeClientSequencePropsWatchers = exports.unsubscribeFromSequencePropsWatchers = exports.subscribeToSequencePropsWatchers = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
+ const renderer_1 = require("@remotion/renderer");
9
+ const studio_shared_1 = require("@remotion/studio-shared");
8
10
  const file_watcher_1 = require("../file-watcher");
9
11
  const live_events_1 = require("./live-events");
10
12
  const node_path_cache_1 = require("./node-path-cache");
11
13
  const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
12
14
  const sequencePropsWatchers = {};
13
- const makeWatcherKey = ({ absolutePath, nodePath, }) => {
14
- return `${absolutePath}:${JSON.stringify(nodePath)}`;
15
- };
16
- const getSequencePropsStatus = ({ fileName, line, column, keys, remotionRoot, }) => {
15
+ const getSequencePropsStatus = ({ fileName, line, column, keys, effects, remotionRoot, logLevel, }) => {
17
16
  // Try cached nodePath first (handles stale source maps after suppressed rebuilds)
18
17
  const cachedNodePath = (0, node_path_cache_1.getCachedNodePath)(fileName, line, column);
19
18
  if (cachedNodePath) {
@@ -21,37 +20,51 @@ const getSequencePropsStatus = ({ fileName, line, column, keys, remotionRoot, })
21
20
  fileName,
22
21
  nodePath: cachedNodePath,
23
22
  keys,
23
+ effects,
24
24
  remotionRoot,
25
25
  });
26
26
  if (cachedResult.canUpdate) {
27
- return { status: cachedResult, nodePath: cachedNodePath, success: true };
27
+ return {
28
+ status: cachedResult,
29
+ nodePath: {
30
+ absolutePath: node_path_1.default.resolve(remotionRoot, fileName),
31
+ nodePath: cachedNodePath,
32
+ sequenceKeys: keys,
33
+ effectKeys: effects,
34
+ },
35
+ success: true,
36
+ };
28
37
  }
29
38
  }
30
39
  const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromFilenameByLine)({
31
40
  fileName,
32
41
  line,
33
42
  keys,
43
+ effects,
34
44
  remotionRoot,
45
+ logLevel,
35
46
  });
36
47
  return status;
37
48
  };
38
- const subscribeToSequencePropsWatchers = ({ fileName, line, column, keys, remotionRoot, clientId, }) => {
49
+ const subscribeToSequencePropsWatchers = ({ fileName, line, column, keys, effects, remotionRoot, clientId, logLevel, }) => {
39
50
  var _a;
40
51
  const initialResult = getSequencePropsStatus({
41
52
  fileName,
42
53
  line,
43
54
  column,
44
55
  keys,
56
+ effects,
45
57
  remotionRoot,
58
+ logLevel,
46
59
  });
47
60
  if (!initialResult.success) {
48
61
  return initialResult;
49
62
  }
50
63
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
51
64
  // Cache the resolved nodePath for future lookups with stale source maps
52
- (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath);
65
+ (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath.nodePath);
53
66
  const { nodePath } = initialResult;
54
- const watcherKey = makeWatcherKey({ absolutePath, nodePath });
67
+ const watcherKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
55
68
  // If a watcher already exists for this key, just bump the ref count
56
69
  if ((_a = sequencePropsWatchers[clientId]) === null || _a === void 0 ? void 0 : _a[watcherKey]) {
57
70
  sequencePropsWatchers[clientId][watcherKey].refCount++;
@@ -64,21 +77,32 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, keys, remoti
64
77
  if (event.type === 'deleted') {
65
78
  return;
66
79
  }
67
- let result;
68
80
  try {
69
- result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)(event.content, nodePath, keys);
81
+ const result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
82
+ fileContents: event.content,
83
+ nodePath: nodePath.nodePath,
84
+ keys,
85
+ effects,
86
+ });
87
+ const previousEffectChain = result.effects.map((effect) => effect.canUpdate && effect.callee);
88
+ const newEffectChain = initialResult.success &&
89
+ initialResult.status.effects.map((effect) => effect.canUpdate && effect.callee);
90
+ if (previousEffectChain.join(',') !== newEffectChain.join(',')) {
91
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, 'Effect chain changed, not sending "sequence-props-updated" event');
92
+ return;
93
+ }
94
+ (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
95
+ listener.sendEventToClientId(clientId, {
96
+ type: 'sequence-props-updated',
97
+ fileName,
98
+ nodePath,
99
+ result,
100
+ });
101
+ });
70
102
  }
71
- catch (_a) {
72
- return;
103
+ catch (error) {
104
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, error);
73
105
  }
74
- (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
75
- listener.sendEventToClientId(clientId, {
76
- type: 'sequence-props-updated',
77
- fileName,
78
- nodePath,
79
- result,
80
- });
81
- });
82
106
  },
83
107
  });
84
108
  if (!sequencePropsWatchers[clientId]) {
@@ -88,9 +112,14 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, keys, remoti
88
112
  return initialResult;
89
113
  };
90
114
  exports.subscribeToSequencePropsWatchers = subscribeToSequencePropsWatchers;
91
- const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, }) => {
115
+ const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, }) => {
92
116
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
93
- const watcherKey = makeWatcherKey({ absolutePath, nodePath });
117
+ const watcherKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)({
118
+ absolutePath,
119
+ nodePath,
120
+ sequenceKeys,
121
+ effectKeys,
122
+ });
94
123
  if (!sequencePropsWatchers[clientId] ||
95
124
  !sequencePropsWatchers[clientId][watcherKey]) {
96
125
  return;