@remotion/studio-server 4.0.438 → 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.
Files changed (36) hide show
  1. package/dist/client-render-queue.js +3 -3
  2. package/dist/codemods/apply-visual-control.js +8 -1
  3. package/dist/codemods/format-inline-content.d.ts +21 -0
  4. package/dist/codemods/format-inline-content.js +108 -0
  5. package/dist/codemods/read-visual-control-values.d.ts +7 -0
  6. package/dist/codemods/read-visual-control-values.js +166 -0
  7. package/dist/codemods/update-default-props.d.ts +4 -1
  8. package/dist/codemods/update-default-props.js +51 -22
  9. package/dist/file-watcher.d.ts +24 -7
  10. package/dist/file-watcher.js +148 -29
  11. package/dist/index.d.ts +5 -2
  12. package/dist/index.js +3 -0
  13. package/dist/preview-server/api-routes.js +8 -2
  14. package/dist/preview-server/default-props-watchers.js +12 -17
  15. package/dist/preview-server/file-existence-watchers.js +3 -3
  16. package/dist/preview-server/hot-middleware/index.d.ts +2 -2
  17. package/dist/preview-server/hot-middleware/index.js +14 -92
  18. package/dist/preview-server/live-events.d.ts +7 -1
  19. package/dist/preview-server/live-events.js +21 -2
  20. package/dist/preview-server/routes/apply-codemod.js +2 -1
  21. package/dist/preview-server/routes/apply-visual-control-change.js +103 -5
  22. package/dist/preview-server/routes/can-update-default-props.d.ts +10 -3
  23. package/dist/preview-server/routes/can-update-default-props.js +138 -13
  24. package/dist/preview-server/routes/can-update-sequence-props.js +4 -0
  25. package/dist/preview-server/routes/log-update.d.ts +8 -0
  26. package/dist/preview-server/routes/log-update.js +60 -27
  27. package/dist/preview-server/routes/save-sequence-props.js +47 -5
  28. package/dist/preview-server/routes/update-default-props.js +41 -4
  29. package/dist/preview-server/sequence-props-watchers.js +4 -9
  30. package/dist/preview-server/start-server.js +16 -9
  31. package/dist/preview-server/undo-stack.d.ts +24 -4
  32. package/dist/preview-server/undo-stack.js +75 -11
  33. package/dist/preview-server/watch-ignore-next-change.d.ts +3 -0
  34. package/dist/preview-server/watch-ignore-next-change.js +12 -0
  35. package/dist/start-studio.js +3 -0
  36. package/package.json +6 -6
@@ -1,9 +1,44 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.canUpdateDefaultPropsHandler = exports.checkIfTypeScriptFile = void 0;
36
+ exports.computeCanUpdateDefaultProps = exports.computeCanUpdateDefaultPropsFromContent = exports.checkIfTypeScriptFile = void 0;
4
37
  const node_fs_1 = require("node:fs");
5
- const update_default_props_1 = require("../../codemods/update-default-props");
38
+ const recast = __importStar(require("recast"));
39
+ const parse_ast_1 = require("../../codemods/parse-ast");
6
40
  const project_info_1 = require("../project-info");
41
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
7
42
  const checkIfTypeScriptFile = (file) => {
8
43
  if (!file.endsWith('.tsx') &&
9
44
  !file.endsWith('.ts') &&
@@ -13,28 +48,118 @@ const checkIfTypeScriptFile = (file) => {
13
48
  }
14
49
  };
15
50
  exports.checkIfTypeScriptFile = checkIfTypeScriptFile;
16
- const canUpdateDefaultPropsHandler = async ({ input: { compositionId }, remotionRoot, entryPoint }) => {
51
+ const extractDefaultPropsFromSource = (input, compositionId) => {
52
+ const ast = (0, parse_ast_1.parseAst)(input);
53
+ let result = null;
54
+ recast.types.visit(ast, {
55
+ visitJSXElement(path) {
56
+ var _a;
57
+ const { openingElement } = path.node;
58
+ const openingName = openingElement.name;
59
+ if (openingName.type !== 'JSXIdentifier' &&
60
+ openingName.type !== 'JSXNamespacedName') {
61
+ this.traverse(path);
62
+ return;
63
+ }
64
+ if (openingName.name !== 'Composition' && openingName.name !== 'Still') {
65
+ this.traverse(path);
66
+ return;
67
+ }
68
+ if (!((_a = openingElement.attributes) === null || _a === void 0 ? void 0 : _a.some((attr) => {
69
+ if (attr.type === 'JSXSpreadAttribute') {
70
+ return;
71
+ }
72
+ if (!attr.value) {
73
+ return;
74
+ }
75
+ if (attr.value.type === 'JSXElement') {
76
+ return;
77
+ }
78
+ if (attr.value.type === 'JSXExpressionContainer') {
79
+ return;
80
+ }
81
+ if (attr.value.type === 'JSXFragment') {
82
+ return;
83
+ }
84
+ return attr.name.name === 'id' && attr.value.value === compositionId;
85
+ }))) {
86
+ this.traverse(path);
87
+ return;
88
+ }
89
+ const defaultPropsAttr = openingElement.attributes.find((attr) => {
90
+ if (attr.type === 'JSXSpreadAttribute') {
91
+ return;
92
+ }
93
+ return attr.name.name === 'defaultProps';
94
+ });
95
+ if (!defaultPropsAttr || defaultPropsAttr.type === 'JSXSpreadAttribute') {
96
+ this.traverse(path);
97
+ return;
98
+ }
99
+ if (!defaultPropsAttr.value ||
100
+ defaultPropsAttr.value.type !== 'JSXExpressionContainer') {
101
+ this.traverse(path);
102
+ return;
103
+ }
104
+ const { expression } = defaultPropsAttr.value;
105
+ if (expression.type === 'JSXEmptyExpression') {
106
+ this.traverse(path);
107
+ return;
108
+ }
109
+ if ((0, can_update_sequence_props_1.isStaticValue)(expression)) {
110
+ const value = (0, can_update_sequence_props_1.extractStaticValue)(expression);
111
+ if (value !== null &&
112
+ typeof value === 'object' &&
113
+ !Array.isArray(value)) {
114
+ result = value;
115
+ }
116
+ }
117
+ this.traverse(path);
118
+ },
119
+ });
120
+ return result;
121
+ };
122
+ const computeCanUpdateDefaultPropsFromContent = (content, compositionId) => {
123
+ try {
124
+ const currentDefaultProps = extractDefaultPropsFromSource(content, compositionId);
125
+ if (currentDefaultProps === null) {
126
+ throw new Error(`Could not find or extract defaultProps for composition "${compositionId}"`);
127
+ }
128
+ return {
129
+ canUpdate: true,
130
+ currentDefaultProps,
131
+ };
132
+ }
133
+ catch (err) {
134
+ return {
135
+ canUpdate: false,
136
+ reason: err.message,
137
+ };
138
+ }
139
+ };
140
+ exports.computeCanUpdateDefaultPropsFromContent = computeCanUpdateDefaultPropsFromContent;
141
+ const computeCanUpdateDefaultProps = async ({ compositionId, remotionRoot, entryPoint, }) => {
17
142
  try {
18
143
  const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
19
144
  if (!projectInfo.rootFile) {
20
145
  throw new Error('Cannot find root file in project');
21
146
  }
22
147
  (0, exports.checkIfTypeScriptFile)(projectInfo.rootFile);
23
- await (0, update_default_props_1.updateDefaultProps)({
24
- compositionId,
25
- input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
26
- newDefaultProps: {},
27
- enumPaths: [],
28
- });
148
+ const input = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
149
+ const result = (0, exports.computeCanUpdateDefaultPropsFromContent)(input, compositionId);
29
150
  return {
30
- canUpdate: true,
151
+ result,
152
+ rootFile: projectInfo.rootFile,
31
153
  };
32
154
  }
33
155
  catch (err) {
34
156
  return {
35
- canUpdate: false,
36
- reason: err.message,
157
+ result: {
158
+ canUpdate: false,
159
+ reason: err.message,
160
+ },
161
+ rootFile: null,
37
162
  };
38
163
  }
39
164
  };
40
- exports.canUpdateDefaultPropsHandler = canUpdateDefaultPropsHandler;
165
+ exports.computeCanUpdateDefaultProps = computeCanUpdateDefaultProps;
@@ -52,6 +52,8 @@ const isStaticValue = (node) => {
52
52
  return ((node.operator === '-' ||
53
53
  node.operator === '+') &&
54
54
  node.argument.type === 'NumericLiteral');
55
+ case 'TSAsExpression':
56
+ return (0, exports.isStaticValue)(node.expression);
55
57
  case 'ArrayExpression':
56
58
  return node.elements.every((el) => el !== null && el.type !== 'SpreadElement' && (0, exports.isStaticValue)(el));
57
59
  case 'ObjectExpression':
@@ -78,6 +80,8 @@ const extractStaticValue = (node) => {
78
80
  }
79
81
  return undefined;
80
82
  }
83
+ case 'TSAsExpression':
84
+ return (0, exports.extractStaticValue)(node.expression);
81
85
  case 'ArrayExpression':
82
86
  return node.elements.map((el) => {
83
87
  if (el === null || el.type === 'SpreadElement') {
@@ -1,3 +1,11 @@
1
+ export declare const warnAboutPrettierOnce: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => void;
2
+ export declare const normalizeQuotes: (str: string) => string;
3
+ export declare const formatPropChange: ({ key, oldValueString, newValueString, defaultValueString, }: {
4
+ key: string;
5
+ oldValueString: string;
6
+ newValueString: string;
7
+ defaultValueString: string | null;
8
+ }) => string;
1
9
  export declare const logUpdate: ({ absolutePath, fileRelativeToRoot, key, oldValueString, newValueString, defaultValueString, formatted, logLevel, }: {
2
10
  absolutePath: string;
3
11
  fileRelativeToRoot: string;
@@ -1,9 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logUpdate = void 0;
3
+ exports.logUpdate = exports.formatPropChange = exports.normalizeQuotes = exports.warnAboutPrettierOnce = void 0;
4
4
  const renderer_1 = require("@remotion/renderer");
5
5
  const make_link_1 = require("../../hyperlinks/make-link");
6
6
  let warnedAboutPrettier = false;
7
+ const warnAboutPrettierOnce = (logLevel) => {
8
+ if (warnedAboutPrettier) {
9
+ return;
10
+ }
11
+ warnedAboutPrettier = true;
12
+ renderer_1.RenderInternals.Log.warn({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.yellow('Could not format with Prettier. File will need to be formatted manually.'));
13
+ };
14
+ exports.warnAboutPrettierOnce = warnAboutPrettierOnce;
7
15
  const normalizeQuotes = (str) => {
8
16
  if (str.length >= 2 &&
9
17
  ((str.startsWith("'") && str.endsWith("'")) ||
@@ -12,45 +20,71 @@ const normalizeQuotes = (str) => {
12
20
  }
13
21
  return str;
14
22
  };
15
- const formatValueChange = ({ oldValueString, newValueString, defaultValueString, }) => {
16
- // Changed to default value (prop gets deleted) → show only old value in red
17
- if (defaultValueString !== null && newValueString === defaultValueString) {
18
- return renderer_1.RenderInternals.chalk.red(oldValueString);
23
+ exports.normalizeQuotes = normalizeQuotes;
24
+ // 24-bit ANSI helpers
25
+ const fg = (r, g, b, str) => `\u001b[38;2;${r};${g};${b}m${str}\u001b[39m`;
26
+ const bg = (r, g, b, str) => `\u001b[48;2;${r};${g};${b}m${str}\u001b[49m`;
27
+ // Monokai-inspired syntax colors
28
+ const attrName = (str) => fg(166, 226, 46, str);
29
+ const equals = (str) => fg(249, 38, 114, str);
30
+ const punctuation = (str) => fg(248, 248, 242, str);
31
+ const stringValue = (str) => fg(230, 219, 116, str);
32
+ const numberValue = (str) => fg(174, 129, 255, str);
33
+ const colorValue = (str) => {
34
+ if ((str.startsWith("'") && str.endsWith("'")) ||
35
+ (str.startsWith('"') && str.endsWith('"'))) {
36
+ return stringValue(str);
19
37
  }
20
- // Changed from default value (prop gets added) → show only new value in green
21
- if (defaultValueString !== null && oldValueString === defaultValueString) {
22
- return renderer_1.RenderInternals.chalk.green(newValueString);
38
+ if (/^-?\d+(\.\d+)?$/.test(str)) {
39
+ return numberValue(str);
23
40
  }
24
- return `${renderer_1.RenderInternals.chalk.red(oldValueString)} \u2192 ${renderer_1.RenderInternals.chalk.green(newValueString)}`;
41
+ return punctuation(str);
42
+ };
43
+ // Subtle background tints
44
+ const removedBg = (str) => bg(80, 20, 20, str);
45
+ const addedBg = (str) => bg(30, 80, 30, str);
46
+ const colorEnabled = () => renderer_1.RenderInternals.chalk.enabled();
47
+ // Format key={value} with Monokai syntax highlighting
48
+ const formatSimpleProp = (key, value) => {
49
+ return `${attrName(key)}${equals('=')}${punctuation('{')}${colorValue(value)}${punctuation('}')}`;
50
+ };
51
+ // Format parentKey={{childKey: value}} with Monokai syntax highlighting
52
+ const formatNestedProp = (parentKey, childKey, value) => {
53
+ return `${attrName(parentKey)}${equals('=')}${punctuation('{{')}${punctuation(childKey)}${punctuation(':')} ${colorValue(value)}${punctuation('}}')}`;
25
54
  };
26
55
  const formatPropChange = ({ key, oldValueString, newValueString, defaultValueString, }) => {
56
+ if (!colorEnabled()) {
57
+ const dotIdx = key.indexOf('.');
58
+ if (dotIdx === -1) {
59
+ return `${key}={${oldValueString}} \u2192 ${key}={${newValueString}}`;
60
+ }
61
+ const parent = key.slice(0, dotIdx);
62
+ const child = key.slice(dotIdx + 1);
63
+ return `${parent}={{${child}: ${oldValueString}}} \u2192 ${parent}={{${child}: ${newValueString}}}`;
64
+ }
27
65
  const isResetToDefault = defaultValueString !== null && newValueString === defaultValueString;
28
66
  const isChangeFromDefault = defaultValueString !== null && oldValueString === defaultValueString;
29
- const valueChange = formatValueChange({
30
- oldValueString,
31
- newValueString,
32
- defaultValueString,
33
- });
34
67
  const dotIndex = key.indexOf('.');
35
68
  if (dotIndex === -1) {
36
69
  if (isResetToDefault) {
37
- return renderer_1.RenderInternals.chalk.red(`${key}={${oldValueString}}`);
70
+ return removedBg(formatSimpleProp(key, oldValueString));
38
71
  }
39
72
  if (isChangeFromDefault) {
40
- return renderer_1.RenderInternals.chalk.green(`${key}={${newValueString}}`);
73
+ return addedBg(formatSimpleProp(key, newValueString));
41
74
  }
42
- return `${key}={${valueChange}}`;
75
+ return `${removedBg(formatSimpleProp(key, oldValueString))} \u2192 ${addedBg(formatSimpleProp(key, newValueString))}`;
43
76
  }
44
77
  const parentKey = key.slice(0, dotIndex);
45
78
  const childKey = key.slice(dotIndex + 1);
46
79
  if (isResetToDefault) {
47
- return `${parentKey}={{${renderer_1.RenderInternals.chalk.red(`${childKey}: ${oldValueString}`)}}}`;
80
+ return removedBg(formatNestedProp(parentKey, childKey, oldValueString));
48
81
  }
49
82
  if (isChangeFromDefault) {
50
- return `${parentKey}={{${renderer_1.RenderInternals.chalk.green(`${childKey}: ${newValueString}`)}}}`;
83
+ return addedBg(formatNestedProp(parentKey, childKey, newValueString));
51
84
  }
52
- return `${parentKey}={{${childKey}: ${valueChange}}}`;
85
+ return `${removedBg(formatNestedProp(parentKey, childKey, oldValueString))} \u2192 ${addedBg(formatNestedProp(parentKey, childKey, newValueString))}`;
53
86
  };
87
+ exports.formatPropChange = formatPropChange;
54
88
  const logUpdate = ({ absolutePath, fileRelativeToRoot, key, oldValueString, newValueString, defaultValueString, formatted, logLevel, }) => {
55
89
  const locationLabel = `${fileRelativeToRoot}`;
56
90
  const fileLink = (0, make_link_1.makeHyperlink)({
@@ -58,16 +92,15 @@ const logUpdate = ({ absolutePath, fileRelativeToRoot, key, oldValueString, newV
58
92
  text: locationLabel,
59
93
  fallback: locationLabel,
60
94
  });
61
- const propChange = formatPropChange({
95
+ const propChange = (0, exports.formatPropChange)({
62
96
  key,
63
- oldValueString: normalizeQuotes(oldValueString),
64
- newValueString: normalizeQuotes(newValueString),
65
- defaultValueString: defaultValueString !== null ? normalizeQuotes(defaultValueString) : null,
97
+ oldValueString: (0, exports.normalizeQuotes)(oldValueString),
98
+ newValueString: (0, exports.normalizeQuotes)(newValueString),
99
+ defaultValueString: defaultValueString !== null ? (0, exports.normalizeQuotes)(defaultValueString) : null,
66
100
  });
67
101
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${fileLink}:`)} ${propChange}`);
68
- if (!formatted && !warnedAboutPrettier) {
69
- warnedAboutPrettier = true;
70
- renderer_1.RenderInternals.Log.warn({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.yellow('Could not format with Prettier. File will need to be formatted manually.'));
102
+ if (!formatted) {
103
+ (0, exports.warnAboutPrettierOnce)(logLevel);
71
104
  }
72
105
  };
73
106
  exports.logUpdate = logUpdate;
@@ -6,11 +6,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.saveSequencePropsHandler = void 0;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
+ const renderer_1 = require("@remotion/renderer");
9
10
  const update_sequence_props_1 = require("../../codemods/update-sequence-props");
10
- const hmr_suppression_1 = require("../hmr-suppression");
11
+ const file_watcher_1 = require("../../file-watcher");
12
+ const undo_stack_1 = require("../undo-stack");
13
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
14
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
11
15
  const log_update_1 = require("./log-update");
12
- const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, value, defaultValue }, remotionRoot, logLevel, }) => {
16
+ const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, value, defaultValue, observedKeys }, remotionRoot, logLevel, }) => {
13
17
  try {
18
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-sequence-props] Received request for fileName="${fileName}" key="${key}"`);
14
19
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
15
20
  const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
16
21
  if (fileRelativeToRoot.startsWith('..')) {
@@ -24,28 +29,65 @@ const saveSequencePropsHandler = async ({ input: { fileName, nodePath, key, valu
24
29
  value: JSON.parse(value),
25
30
  defaultValue: defaultValue !== null ? JSON.parse(defaultValue) : null,
26
31
  });
27
- (0, hmr_suppression_1.suppressHmrForFile)(absolutePath);
28
- (0, node_fs_1.writeFileSync)(absolutePath, output);
29
32
  const newValueString = JSON.stringify(JSON.parse(value));
30
33
  const parsedDefault = defaultValue !== null ? JSON.parse(defaultValue) : null;
34
+ const defaultValueString = parsedDefault !== null ? JSON.stringify(parsedDefault) : null;
35
+ const normalizedOld = (0, log_update_1.normalizeQuotes)(oldValueString);
36
+ const normalizedNew = (0, log_update_1.normalizeQuotes)(newValueString);
37
+ const normalizedDefault = defaultValueString !== null ? (0, log_update_1.normalizeQuotes)(defaultValueString) : null;
38
+ const undoPropChange = (0, log_update_1.formatPropChange)({
39
+ key,
40
+ oldValueString: normalizedNew,
41
+ newValueString: normalizedOld,
42
+ defaultValueString: normalizedDefault,
43
+ });
44
+ const redoPropChange = (0, log_update_1.formatPropChange)({
45
+ key,
46
+ oldValueString: normalizedOld,
47
+ newValueString: normalizedNew,
48
+ defaultValueString: normalizedDefault,
49
+ });
50
+ (0, undo_stack_1.pushToUndoStack)({
51
+ filePath: absolutePath,
52
+ oldContents: fileContents,
53
+ logLevel,
54
+ remotionRoot,
55
+ description: {
56
+ undoMessage: `Undid ${undoPropChange}`,
57
+ redoMessage: `Redid ${redoPropChange}`,
58
+ },
59
+ entryType: 'sequence-props',
60
+ });
61
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
62
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
63
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output);
31
64
  (0, log_update_1.logUpdate)({
32
65
  absolutePath,
33
66
  fileRelativeToRoot,
34
67
  key,
35
68
  oldValueString,
36
69
  newValueString,
37
- defaultValueString: parsedDefault !== null ? JSON.stringify(parsedDefault) : null,
70
+ defaultValueString,
38
71
  formatted,
39
72
  logLevel,
40
73
  });
74
+ (0, undo_stack_1.printUndoHint)(logLevel);
75
+ const newStatus = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
76
+ fileName,
77
+ keys: observedKeys,
78
+ nodePath,
79
+ remotionRoot,
80
+ });
41
81
  return {
42
82
  success: true,
83
+ newStatus,
43
84
  };
44
85
  }
45
86
  catch (err) {
46
87
  return {
47
88
  success: false,
48
89
  reason: err.message,
90
+ stack: err.stack,
49
91
  };
50
92
  }
51
93
  };
@@ -1,24 +1,61 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.updateDefaultPropsHandler = void 0;
4
7
  const node_fs_1 = require("node:fs");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const renderer_1 = require("@remotion/renderer");
5
10
  const update_default_props_1 = require("../../codemods/update-default-props");
11
+ const file_watcher_1 = require("../../file-watcher");
12
+ const make_link_1 = require("../../hyperlinks/make-link");
6
13
  const project_info_1 = require("../project-info");
14
+ const undo_stack_1 = require("../undo-stack");
15
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
7
16
  const can_update_default_props_1 = require("./can-update-default-props");
8
- const updateDefaultPropsHandler = async ({ input: { compositionId, defaultProps, enumPaths }, remotionRoot, entryPoint, }) => {
17
+ const log_update_1 = require("./log-update");
18
+ const updateDefaultPropsHandler = async ({ input: { compositionId, defaultProps, enumPaths }, remotionRoot, entryPoint, logLevel, }) => {
9
19
  try {
20
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[update-default-props] Received request for compositionId="${compositionId}"`);
10
21
  const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
11
22
  if (!projectInfo.rootFile) {
12
23
  throw new Error('Cannot find root file in project');
13
24
  }
14
25
  (0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
15
- const updated = await (0, update_default_props_1.updateDefaultProps)({
26
+ const fileContents = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
27
+ const { output, formatted } = await (0, update_default_props_1.updateDefaultProps)({
16
28
  compositionId,
17
- input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
29
+ input: fileContents,
18
30
  newDefaultProps: JSON.parse(defaultProps),
19
31
  enumPaths,
20
32
  });
21
- (0, node_fs_1.writeFileSync)(projectInfo.rootFile, updated);
33
+ (0, undo_stack_1.pushToUndoStack)({
34
+ filePath: projectInfo.rootFile,
35
+ oldContents: fileContents,
36
+ logLevel,
37
+ remotionRoot,
38
+ description: {
39
+ undoMessage: `Undid default props update for "${compositionId}"`,
40
+ redoMessage: `Redid default props update for "${compositionId}"`,
41
+ },
42
+ entryType: 'default-props',
43
+ });
44
+ (0, undo_stack_1.suppressUndoStackInvalidation)(projectInfo.rootFile);
45
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(projectInfo.rootFile);
46
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(projectInfo.rootFile, output);
47
+ const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, projectInfo.rootFile);
48
+ const locationLabel = `${fileRelativeToRoot}`;
49
+ const fileLink = (0, make_link_1.makeHyperlink)({
50
+ url: `file://${projectInfo.rootFile}`,
51
+ text: locationLabel,
52
+ fallback: locationLabel,
53
+ });
54
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${fileLink}:`)} Updated default props for "${compositionId}"`);
55
+ if (!formatted) {
56
+ (0, log_update_1.warnAboutPrettierOnce)(logLevel);
57
+ }
58
+ (0, undo_stack_1.printUndoHint)(logLevel);
22
59
  return {
23
60
  success: true,
24
61
  };
@@ -33,18 +33,13 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, keys, remotionRoot,
33
33
  }
34
34
  const { unwatch } = (0, file_watcher_1.installFileWatcher)({
35
35
  file: absolutePath,
36
- onChange: (type) => {
37
- if (type === 'deleted') {
36
+ onChange: (event) => {
37
+ if (event.type === 'deleted') {
38
38
  return;
39
39
  }
40
- const result = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
41
- fileName,
42
- nodePath,
43
- keys,
44
- remotionRoot,
45
- });
40
+ const result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)(event.content, nodePath, keys);
46
41
  (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
47
- listener.sendEventToClient({
42
+ listener.sendEventToClientId(clientId, {
48
43
  type: 'sequence-props-updated',
49
44
  fileName,
50
45
  nodePath,
@@ -12,6 +12,8 @@ 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 undo_stack_1 = require("./undo-stack");
16
+ const watch_ignore_next_change_1 = require("./watch-ignore-next-change");
15
17
  const startServer = async (options) => {
16
18
  var _a, _b, _c;
17
19
  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;
@@ -26,6 +28,9 @@ const startServer = async (options) => {
26
28
  });
27
29
  return detection.type === 'match' ? 'stop' : 'continue';
28
30
  };
31
+ const watchIgnorePlugin = new bundler_1.WatchIgnoreNextChangePlugin((...args) => {
32
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel: options.logLevel }, ...args);
33
+ });
29
34
  const configArgs = {
30
35
  entry: options.entry,
31
36
  userDefinedComponent: options.userDefinedComponent,
@@ -40,6 +45,7 @@ const startServer = async (options) => {
40
45
  poll: options.poll,
41
46
  bufferStateDelayInMilliseconds: options.bufferStateDelayInMilliseconds,
42
47
  askAIEnabled: options.askAIEnabled,
48
+ extraPlugins: [watchIgnorePlugin],
43
49
  };
44
50
  let compiler;
45
51
  if (options.rspack) {
@@ -50,9 +56,17 @@ const startServer = async (options) => {
50
56
  const [, webpackConf] = await bundler_1.BundlerInternals.webpackConfig(configArgs);
51
57
  compiler = (0, bundler_1.webpack)(webpackConf);
52
58
  }
59
+ (0, watch_ignore_next_change_1.setWatchIgnoreNextChangePlugin)(watchIgnorePlugin);
53
60
  const wdmMiddleware = (0, dev_middleware_1.wdm)(compiler, options.logLevel);
54
- const whm = (0, hot_middleware_1.webpackHotMiddleware)(compiler, options.logLevel);
55
- const liveEventsServer = (0, live_events_1.makeLiveEventsRouter)(options.logLevel);
61
+ const liveEventsServer = (0, live_events_1.makeLiveEventsRouter)(options.logLevel, () => {
62
+ const undoStack = (0, undo_stack_1.getUndoStack)();
63
+ const redoStack = (0, undo_stack_1.getRedoStack)();
64
+ return {
65
+ undoFile: undoStack.length > 0 ? undoStack[undoStack.length - 1].filePath : null,
66
+ redoFile: redoStack.length > 0 ? redoStack[redoStack.length - 1].filePath : null,
67
+ };
68
+ });
69
+ (0, hot_middleware_1.setupWebpackHmr)(compiler, options.logLevel, liveEventsServer);
56
70
  const server = node_http_1.default.createServer((request, response) => {
57
71
  if (options.enableCrossSiteIsolation) {
58
72
  response.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@@ -62,13 +76,6 @@ const startServer = async (options) => {
62
76
  wdmMiddleware(request, response, () => {
63
77
  resolve();
64
78
  });
65
- })
66
- .then(() => {
67
- return new Promise((resolve) => {
68
- whm(request, response, () => {
69
- resolve();
70
- });
71
- });
72
79
  })
73
80
  .then(() => {
74
81
  return (0, routes_1.handleRoutes)({
@@ -1,10 +1,30 @@
1
1
  import type { LogLevel } from '@remotion/renderer';
2
- interface UndoEntry {
2
+ export interface UndoEntryDescription {
3
+ undoMessage: string;
4
+ redoMessage: string;
5
+ }
6
+ type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props';
7
+ type UndoEntry = {
3
8
  filePath: string;
4
9
  oldContents: string;
5
- }
6
- export declare function pushToUndoStack(filePath: string, oldContents: string, logLevel: LogLevel): void;
7
- export declare function pushToRedoStack(filePath: string, oldContents: string): void;
10
+ description: UndoEntryDescription;
11
+ } & ({
12
+ entryType: 'visual-control';
13
+ } | {
14
+ entryType: 'default-props';
15
+ } | {
16
+ entryType: 'sequence-props';
17
+ });
18
+ export declare function pushToUndoStack({ filePath, oldContents, logLevel, remotionRoot, description, entryType }: {
19
+ filePath: string;
20
+ oldContents: string;
21
+ logLevel: LogLevel;
22
+ remotionRoot: string;
23
+ description: UndoEntryDescription;
24
+ entryType: UndoEntryType;
25
+ }): void;
26
+ export declare function printUndoHint(logLevel: LogLevel): void;
27
+ export declare function pushToRedoStack(filePath: string, oldContents: string, description: UndoEntryDescription, entryType: UndoEntryType): void;
8
28
  export declare function suppressUndoStackInvalidation(filePath: string): void;
9
29
  export declare function popUndo(): {
10
30
  success: true;