@remotion/studio-server 4.0.476 → 4.0.477
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.
- package/dist/helpers/resolve-composition-component.js +19 -9
- package/dist/preview-server/jsx-component-identity.d.ts +12 -0
- package/dist/preview-server/jsx-component-identity.js +126 -0
- package/dist/preview-server/routes/add-sequence-keyframe.js +1 -0
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +6 -3
- package/dist/preview-server/routes/can-update-sequence-props.js +31 -3
- package/dist/preview-server/routes/delete-keyframes.js +1 -0
- package/dist/preview-server/routes/download-remote-asset.js +1 -0
- package/dist/preview-server/routes/insert-jsx-element.js +9 -0
- package/dist/preview-server/routes/save-sequence-props.js +1 -0
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +2 -1
- package/dist/preview-server/routes/update-sequence-keyframe-settings.js +1 -0
- package/dist/preview-server/sequence-props-watchers.d.ts +2 -1
- package/dist/preview-server/sequence-props-watchers.js +53 -27
- package/package.json +6 -6
|
@@ -515,10 +515,15 @@ const createStringAttribute = (name, value) => {
|
|
|
515
515
|
const createBooleanAttribute = (name, value) => {
|
|
516
516
|
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.booleanLiteral(value)));
|
|
517
517
|
};
|
|
518
|
-
const
|
|
519
|
-
|
|
518
|
+
const formatTranslateValue = ({ x, y }) => `${x}px ${y}px`;
|
|
519
|
+
const createPositionAbsoluteStyleAttribute = (position) => {
|
|
520
|
+
const properties = [
|
|
520
521
|
recast.types.builders.objectProperty(recast.types.builders.identifier('position'), recast.types.builders.stringLiteral('absolute')),
|
|
521
|
-
]
|
|
522
|
+
];
|
|
523
|
+
if (position) {
|
|
524
|
+
properties.push(recast.types.builders.objectProperty(recast.types.builders.identifier('translate'), recast.types.builders.stringLiteral(formatTranslateValue(position))));
|
|
525
|
+
}
|
|
526
|
+
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('style'), recast.types.builders.jsxExpressionContainer(recast.types.builders.objectExpression(properties)));
|
|
522
527
|
};
|
|
523
528
|
const createStaticFileSrcAttribute = ({ staticFileLocalName, src, }) => {
|
|
524
529
|
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('src'), recast.types.builders.jsxExpressionContainer(recast.types.builders.callExpression(recast.types.builders.identifier(staticFileLocalName), [recast.types.builders.stringLiteral(src)])));
|
|
@@ -535,25 +540,27 @@ const createComponentProp = ({ name, value, }) => {
|
|
|
535
540
|
const createStringSrcAttribute = (src) => {
|
|
536
541
|
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('src'), recast.types.builders.stringLiteral(src));
|
|
537
542
|
};
|
|
538
|
-
const createSolidElement = ({ localName, width, height, }) => {
|
|
543
|
+
const createSolidElement = ({ localName, width, height, position, }) => {
|
|
539
544
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
540
545
|
createNumberAttribute('width', width),
|
|
541
546
|
createNumberAttribute('height', height),
|
|
542
|
-
createPositionAbsoluteStyleAttribute(),
|
|
547
|
+
createPositionAbsoluteStyleAttribute(position),
|
|
543
548
|
], true), null, []);
|
|
544
549
|
};
|
|
545
|
-
const createComponentElement = ({ localName, props, }) => {
|
|
550
|
+
const createComponentElement = ({ localName, props, position, }) => {
|
|
546
551
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
547
552
|
...props.map(createComponentProp),
|
|
548
|
-
createPositionAbsoluteStyleAttribute(),
|
|
553
|
+
createPositionAbsoluteStyleAttribute(position),
|
|
549
554
|
], true), null, []);
|
|
550
555
|
};
|
|
551
|
-
const createAssetElement = ({ addPositionStyle, localName, staticFileLocalName, src, dimensions, }) => {
|
|
556
|
+
const createAssetElement = ({ addPositionStyle, localName, staticFileLocalName, src, dimensions, position, }) => {
|
|
552
557
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
553
558
|
staticFileLocalName === null
|
|
554
559
|
? createStringSrcAttribute(src)
|
|
555
560
|
: createStaticFileSrcAttribute({ staticFileLocalName, src }),
|
|
556
|
-
...(addPositionStyle
|
|
561
|
+
...(addPositionStyle
|
|
562
|
+
? [createPositionAbsoluteStyleAttribute(position)]
|
|
563
|
+
: []),
|
|
557
564
|
...(dimensions
|
|
558
565
|
? [
|
|
559
566
|
createNumberAttribute('width', dimensions.width),
|
|
@@ -1007,6 +1014,7 @@ const createInsertableJsxElement = ({ ast, element, }) => {
|
|
|
1007
1014
|
localName: solidLocalName,
|
|
1008
1015
|
width: element.width,
|
|
1009
1016
|
height: element.height,
|
|
1017
|
+
position: element.position,
|
|
1010
1018
|
});
|
|
1011
1019
|
}
|
|
1012
1020
|
if (element.type === 'component') {
|
|
@@ -1019,6 +1027,7 @@ const createInsertableJsxElement = ({ ast, element, }) => {
|
|
|
1019
1027
|
return createComponentElement({
|
|
1020
1028
|
localName: componentLocalName,
|
|
1021
1029
|
props: element.props,
|
|
1030
|
+
position: element.position,
|
|
1022
1031
|
});
|
|
1023
1032
|
}
|
|
1024
1033
|
if (element.type === 'asset') {
|
|
@@ -1048,6 +1057,7 @@ const createInsertableJsxElement = ({ ast, element, }) => {
|
|
|
1048
1057
|
staticFileLocalName,
|
|
1049
1058
|
src: element.src,
|
|
1050
1059
|
dimensions: element.dimensions,
|
|
1060
|
+
position: element.position,
|
|
1051
1061
|
});
|
|
1052
1062
|
}
|
|
1053
1063
|
throw new Error('Unsupported element type');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { File, JSXOpeningElement } from '@babel/types';
|
|
2
|
+
export declare class JsxElementIdentityMismatchError extends Error {
|
|
3
|
+
constructor();
|
|
4
|
+
}
|
|
5
|
+
export declare const getJsxComponentIdentity: ({ ast, jsxElement, }: {
|
|
6
|
+
ast: File;
|
|
7
|
+
jsxElement: JSXOpeningElement;
|
|
8
|
+
}) => string | null;
|
|
9
|
+
export declare const jsxComponentIdentitiesMatch: ({ expected, actual, }: {
|
|
10
|
+
expected: string | null;
|
|
11
|
+
actual: string | null;
|
|
12
|
+
}) => boolean;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jsxComponentIdentitiesMatch = exports.getJsxComponentIdentity = exports.JsxElementIdentityMismatchError = void 0;
|
|
4
|
+
const imports_1 = require("../helpers/imports");
|
|
5
|
+
class JsxElementIdentityMismatchError extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('JSX element identity changed');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.JsxElementIdentityMismatchError = JsxElementIdentityMismatchError;
|
|
11
|
+
const jsxMemberToString = (expr) => {
|
|
12
|
+
if (expr.type === 'JSXIdentifier') {
|
|
13
|
+
return expr.name;
|
|
14
|
+
}
|
|
15
|
+
return `${jsxMemberToString(expr.object)}.${expr.property.name}`;
|
|
16
|
+
};
|
|
17
|
+
const getJsxRootIdentifier = (expr) => {
|
|
18
|
+
if (expr.type === 'JSXIdentifier') {
|
|
19
|
+
return expr;
|
|
20
|
+
}
|
|
21
|
+
return getJsxRootIdentifier(expr.object);
|
|
22
|
+
};
|
|
23
|
+
const getTagName = (node) => {
|
|
24
|
+
if (node.name.type === 'JSXIdentifier') {
|
|
25
|
+
return node.name.name;
|
|
26
|
+
}
|
|
27
|
+
if (node.name.type === 'JSXMemberExpression') {
|
|
28
|
+
return jsxMemberToString(node.name);
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
const getMemberPath = (tagName) => {
|
|
33
|
+
const dotIndex = tagName.indexOf('.');
|
|
34
|
+
return dotIndex === -1 ? '' : tagName.slice(dotIndex + 1);
|
|
35
|
+
};
|
|
36
|
+
const getMemberPathAfterImportName = ({ tagName, importName, }) => {
|
|
37
|
+
const parts = tagName.split('.');
|
|
38
|
+
const importNameIndex = parts.indexOf(importName);
|
|
39
|
+
if (importNameIndex === -1) {
|
|
40
|
+
return getMemberPath(tagName);
|
|
41
|
+
}
|
|
42
|
+
return parts.slice(importNameIndex + 1).join('.');
|
|
43
|
+
};
|
|
44
|
+
const sourcePathToIdentityPrefix = (sourcePath) => {
|
|
45
|
+
if (sourcePath === 'remotion') {
|
|
46
|
+
return 'dev.remotion.remotion';
|
|
47
|
+
}
|
|
48
|
+
if (sourcePath.startsWith('@remotion/')) {
|
|
49
|
+
const packageName = sourcePath
|
|
50
|
+
.slice('@remotion/'.length)
|
|
51
|
+
.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
52
|
+
return `dev.remotion.${packageName}`;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
const makeImportedIdentity = ({ sourcePath, importName, memberPath, }) => {
|
|
57
|
+
const prefix = sourcePathToIdentityPrefix(sourcePath);
|
|
58
|
+
if (prefix === null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return [prefix, importName, memberPath].filter(Boolean).join('.');
|
|
62
|
+
};
|
|
63
|
+
const getJsxComponentIdentity = ({ ast, jsxElement, }) => {
|
|
64
|
+
var _a;
|
|
65
|
+
const tagName = getTagName(jsxElement);
|
|
66
|
+
if (tagName === null) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const rootIdentifier = jsxElement.name.type === 'JSXIdentifier'
|
|
70
|
+
? jsxElement.name
|
|
71
|
+
: jsxElement.name.type === 'JSXMemberExpression'
|
|
72
|
+
? getJsxRootIdentifier(jsxElement.name)
|
|
73
|
+
: null;
|
|
74
|
+
if (rootIdentifier === null) {
|
|
75
|
+
return tagName;
|
|
76
|
+
}
|
|
77
|
+
for (const node of ast.program.body) {
|
|
78
|
+
if (node.type !== 'ImportDeclaration') {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const sourcePath = String(node.source.value);
|
|
82
|
+
for (const specifier of node.specifiers) {
|
|
83
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
84
|
+
((_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) === rootIdentifier.name) {
|
|
85
|
+
const importName = (0, imports_1.getImportedName)(specifier);
|
|
86
|
+
return makeImportedIdentity({
|
|
87
|
+
sourcePath,
|
|
88
|
+
importName,
|
|
89
|
+
memberPath: getMemberPath(tagName),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (specifier.type === 'ImportNamespaceSpecifier' &&
|
|
93
|
+
specifier.local.name === rootIdentifier.name) {
|
|
94
|
+
const [importName, ...members] = getMemberPath(tagName).split('.');
|
|
95
|
+
if (!importName) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return makeImportedIdentity({
|
|
99
|
+
sourcePath,
|
|
100
|
+
importName,
|
|
101
|
+
memberPath: members.join('.'),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (specifier.type === 'ImportDefaultSpecifier' &&
|
|
105
|
+
specifier.local.name === rootIdentifier.name) {
|
|
106
|
+
return makeImportedIdentity({
|
|
107
|
+
sourcePath,
|
|
108
|
+
importName: 'default',
|
|
109
|
+
memberPath: getMemberPathAfterImportName({
|
|
110
|
+
tagName,
|
|
111
|
+
importName: rootIdentifier.name,
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return tagName;
|
|
118
|
+
};
|
|
119
|
+
exports.getJsxComponentIdentity = getJsxComponentIdentity;
|
|
120
|
+
const jsxComponentIdentitiesMatch = ({ expected, actual, }) => {
|
|
121
|
+
if (expected === null) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return expected === actual;
|
|
125
|
+
};
|
|
126
|
+
exports.jsxComponentIdentitiesMatch = jsxComponentIdentitiesMatch;
|
|
@@ -74,6 +74,7 @@ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, v
|
|
|
74
74
|
fileContents: output,
|
|
75
75
|
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
76
76
|
nodePath: updatedNodePath,
|
|
77
|
+
componentIdentity: null,
|
|
77
78
|
effects: [],
|
|
78
79
|
});
|
|
79
80
|
const updatedSubscriptionKey = { ...nodePath, nodePath: updatedNodePath };
|
|
@@ -10,22 +10,25 @@ export declare const getComputedStatus: (node: Expression, ast: File) => CanUpda
|
|
|
10
10
|
export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
|
|
11
11
|
export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
|
|
12
12
|
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
13
|
-
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, keys, effects, }: {
|
|
13
|
+
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, componentIdentity, keys, effects, }: {
|
|
14
14
|
fileContents: string;
|
|
15
15
|
nodePath: SequenceNodePath;
|
|
16
|
+
componentIdentity: string | null;
|
|
16
17
|
keys: string[];
|
|
17
18
|
effects: string[][];
|
|
18
19
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
19
|
-
export declare const computeSequencePropsStatus: ({ fileName, nodePath, keys, effects, remotionRoot, }: {
|
|
20
|
+
export declare const computeSequencePropsStatus: ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, }: {
|
|
20
21
|
fileName: string;
|
|
21
22
|
nodePath: SequenceNodePath;
|
|
23
|
+
componentIdentity: string | null;
|
|
22
24
|
keys: string[];
|
|
23
25
|
effects: string[][];
|
|
24
26
|
remotionRoot: string;
|
|
25
27
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
26
|
-
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, keys, effects, remotionRoot, logLevel, }: {
|
|
28
|
+
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, }: {
|
|
27
29
|
fileName: string;
|
|
28
30
|
line: number;
|
|
31
|
+
componentIdentity: string | null;
|
|
29
32
|
keys: string[];
|
|
30
33
|
effects: string[][];
|
|
31
34
|
remotionRoot: string;
|
|
@@ -43,6 +43,7 @@ const parse_ast_1 = require("../../codemods/parse-ast");
|
|
|
43
43
|
const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
|
|
44
44
|
const import_agnostic_node_path_1 = require("../../helpers/import-agnostic-node-path");
|
|
45
45
|
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
46
|
+
const jsx_component_identity_1 = require("../jsx-component-identity");
|
|
46
47
|
const jsx_element_not_found_at_location_error_1 = require("../jsx-element-not-found-at-location-error");
|
|
47
48
|
const can_update_effect_props_1 = require("./can-update-effect-props");
|
|
48
49
|
const staticStatus = (codeValue) => ({
|
|
@@ -353,6 +354,25 @@ const getInterpolationKeyframes = (node, ast) => {
|
|
|
353
354
|
if (node.type === 'TSAsExpression') {
|
|
354
355
|
return getInterpolationKeyframes(node.expression, ast);
|
|
355
356
|
}
|
|
357
|
+
if (node.type === 'CallExpression' &&
|
|
358
|
+
node.callee.type === 'Identifier' &&
|
|
359
|
+
node.callee.name === 'String' &&
|
|
360
|
+
node.arguments.length === 1 &&
|
|
361
|
+
node.arguments[0].type !== 'ArgumentPlaceholder' &&
|
|
362
|
+
node.arguments[0].type !== 'JSXNamespacedName' &&
|
|
363
|
+
node.arguments[0].type !== 'SpreadElement') {
|
|
364
|
+
const interpolation = getInterpolationKeyframes(node.arguments[0], ast);
|
|
365
|
+
if (!interpolation) {
|
|
366
|
+
return undefined;
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
...interpolation,
|
|
370
|
+
keyframes: interpolation.keyframes.map((keyframe) => ({
|
|
371
|
+
...keyframe,
|
|
372
|
+
value: String(keyframe.value),
|
|
373
|
+
})),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
356
376
|
if (node.type !== 'CallExpression') {
|
|
357
377
|
return undefined;
|
|
358
378
|
}
|
|
@@ -627,12 +647,18 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, ast, keys, }) => {
|
|
|
627
647
|
}
|
|
628
648
|
return filteredProps;
|
|
629
649
|
};
|
|
630
|
-
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, effects, }) => {
|
|
650
|
+
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, effects, }) => {
|
|
631
651
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
632
652
|
const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
|
|
633
653
|
if (!jsxElement) {
|
|
634
654
|
throw new jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError();
|
|
635
655
|
}
|
|
656
|
+
if (!(0, jsx_component_identity_1.jsxComponentIdentitiesMatch)({
|
|
657
|
+
expected: componentIdentity,
|
|
658
|
+
actual: (0, jsx_component_identity_1.getJsxComponentIdentity)({ ast, jsxElement }),
|
|
659
|
+
})) {
|
|
660
|
+
throw new jsx_component_identity_1.JsxElementIdentityMismatchError();
|
|
661
|
+
}
|
|
636
662
|
const filteredProps = computeSequenceOnlyPropsRecord({ jsxElement, ast, keys });
|
|
637
663
|
const effectsStatuses = computeEffectsForJsx({ ast, jsxElement, effects });
|
|
638
664
|
return {
|
|
@@ -642,7 +668,7 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, e
|
|
|
642
668
|
};
|
|
643
669
|
};
|
|
644
670
|
exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
|
|
645
|
-
const computeSequencePropsStatus = ({ fileName, nodePath, keys, effects, remotionRoot, }) => {
|
|
671
|
+
const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, }) => {
|
|
646
672
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
647
673
|
remotionRoot,
|
|
648
674
|
fileName,
|
|
@@ -652,12 +678,13 @@ const computeSequencePropsStatus = ({ fileName, nodePath, keys, effects, remotio
|
|
|
652
678
|
return (0, exports.computeSequencePropsStatusFromContent)({
|
|
653
679
|
fileContents,
|
|
654
680
|
nodePath,
|
|
681
|
+
componentIdentity,
|
|
655
682
|
keys,
|
|
656
683
|
effects,
|
|
657
684
|
});
|
|
658
685
|
};
|
|
659
686
|
exports.computeSequencePropsStatus = computeSequencePropsStatus;
|
|
660
|
-
const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, effects, remotionRoot, logLevel, }) => {
|
|
687
|
+
const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, }) => {
|
|
661
688
|
try {
|
|
662
689
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
663
690
|
remotionRoot,
|
|
@@ -680,6 +707,7 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, ef
|
|
|
680
707
|
status: (0, exports.computeSequencePropsStatus)({
|
|
681
708
|
fileName,
|
|
682
709
|
nodePath: resolvedNodePath,
|
|
710
|
+
componentIdentity,
|
|
683
711
|
keys,
|
|
684
712
|
effects,
|
|
685
713
|
remotionRoot,
|
|
@@ -215,6 +215,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
|
|
|
215
215
|
fileContents: output,
|
|
216
216
|
keys: (0, studio_shared_1.getAllSchemaKeys)(keyframe.schema),
|
|
217
217
|
nodePath: keyframe.nodePath.nodePath,
|
|
218
|
+
componentIdentity: null,
|
|
218
219
|
effects: [],
|
|
219
220
|
});
|
|
220
221
|
return {
|
|
@@ -14,7 +14,16 @@ const validateDimension = (name, value) => {
|
|
|
14
14
|
throw new Error(`${name} must be a positive number`);
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
|
+
const validatePosition = (position) => {
|
|
18
|
+
if (position === null) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!Number.isFinite(position.x) || !Number.isFinite(position.y)) {
|
|
22
|
+
throw new Error('Position must be finite');
|
|
23
|
+
}
|
|
24
|
+
};
|
|
17
25
|
const validateElement = (element) => {
|
|
26
|
+
validatePosition(element.position);
|
|
18
27
|
if (element.type === 'solid') {
|
|
19
28
|
validateDimension('width', element.width);
|
|
20
29
|
validateDimension('height', element.height);
|
|
@@ -145,6 +145,7 @@ const saveSequencePropsHandler = ({ input: { edits, clientId, undoLabel, redoLab
|
|
|
145
145
|
fileContents: output,
|
|
146
146
|
keys: (0, studio_shared_1.getAllSchemaKeys)(edit.schema),
|
|
147
147
|
nodePath: edit.nodePath.nodePath,
|
|
148
|
+
componentIdentity: null,
|
|
148
149
|
effects: [],
|
|
149
150
|
});
|
|
150
151
|
return {
|
|
@@ -2,12 +2,13 @@
|
|
|
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, column, nodePath, keys, effects, clientId }, remotionRoot, logLevel, }) => {
|
|
5
|
+
const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, componentIdentity, keys, effects, clientId, }, remotionRoot, logLevel, }) => {
|
|
6
6
|
const result = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
|
|
7
7
|
fileName,
|
|
8
8
|
line,
|
|
9
9
|
column,
|
|
10
10
|
nodePath,
|
|
11
|
+
componentIdentity,
|
|
11
12
|
keys,
|
|
12
13
|
effects,
|
|
13
14
|
remotionRoot,
|
|
@@ -77,6 +77,7 @@ const updateSequenceKeyframeSettingsHandler = ({ input: { fileName, nodePath, ke
|
|
|
77
77
|
fileContents: output,
|
|
78
78
|
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
79
79
|
nodePath: updatedNodePath,
|
|
80
|
+
componentIdentity: null,
|
|
80
81
|
effects: [],
|
|
81
82
|
});
|
|
82
83
|
const updatedSubscriptionKey = { ...nodePath, nodePath: updatedNodePath };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
|
|
2
2
|
import type { SequenceNodePath } from 'remotion';
|
|
3
|
-
export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, keys, effects, remotionRoot, clientId, logLevel, }: {
|
|
3
|
+
export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, }: {
|
|
4
4
|
fileName: string;
|
|
5
5
|
line: number;
|
|
6
6
|
column: number;
|
|
7
7
|
nodePath: SequenceNodePath | null;
|
|
8
|
+
componentIdentity: string | null;
|
|
8
9
|
keys: string[];
|
|
9
10
|
effects: string[][];
|
|
10
11
|
remotionRoot: string;
|
|
@@ -8,42 +8,64 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
8
8
|
const renderer_1 = require("@remotion/renderer");
|
|
9
9
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
10
10
|
const file_watcher_1 = require("../file-watcher");
|
|
11
|
+
const jsx_component_identity_1 = require("./jsx-component-identity");
|
|
11
12
|
const jsx_element_not_found_at_location_error_1 = require("./jsx-element-not-found-at-location-error");
|
|
12
13
|
const live_events_1 = require("./live-events");
|
|
13
14
|
const node_path_cache_1 = require("./node-path-cache");
|
|
14
15
|
const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
|
|
15
16
|
const sequencePropsWatchers = {};
|
|
16
|
-
const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, keys, effects, remotionRoot, logLevel, }) => {
|
|
17
|
+
const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, componentIdentity, keys, effects, remotionRoot, logLevel, }) => {
|
|
17
18
|
if (preferredNodePath) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
keys,
|
|
22
|
-
effects,
|
|
23
|
-
remotionRoot,
|
|
24
|
-
});
|
|
25
|
-
return {
|
|
26
|
-
status: fromNodePath,
|
|
27
|
-
nodePath: {
|
|
28
|
-
absolutePath: node_path_1.default.resolve(remotionRoot, fileName),
|
|
19
|
+
try {
|
|
20
|
+
const fromNodePath = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
|
|
21
|
+
fileName,
|
|
29
22
|
nodePath: preferredNodePath,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
componentIdentity,
|
|
24
|
+
keys,
|
|
25
|
+
effects,
|
|
26
|
+
remotionRoot,
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
status: fromNodePath,
|
|
30
|
+
nodePath: {
|
|
31
|
+
absolutePath: node_path_1.default.resolve(remotionRoot, fileName),
|
|
32
|
+
nodePath: preferredNodePath,
|
|
33
|
+
sequenceKeys: keys,
|
|
34
|
+
effectKeys: effects,
|
|
35
|
+
},
|
|
36
|
+
success: true,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (!(error instanceof jsx_component_identity_1.JsxElementIdentityMismatchError ||
|
|
41
|
+
error instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError)) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
// Try cached nodePath first (handles stale source maps after suppressed rebuilds)
|
|
37
47
|
const cachedNodePath = (0, node_path_cache_1.getCachedNodePath)(fileName, line, column);
|
|
38
48
|
if (cachedNodePath) {
|
|
39
|
-
const cachedResult = (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
const cachedResult = (() => {
|
|
50
|
+
try {
|
|
51
|
+
return (0, can_update_sequence_props_1.computeSequencePropsStatus)({
|
|
52
|
+
fileName,
|
|
53
|
+
nodePath: cachedNodePath,
|
|
54
|
+
componentIdentity,
|
|
55
|
+
keys,
|
|
56
|
+
effects,
|
|
57
|
+
remotionRoot,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof jsx_component_identity_1.JsxElementIdentityMismatchError ||
|
|
62
|
+
error instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
if (cachedResult === null || cachedResult === void 0 ? void 0 : cachedResult.canUpdate) {
|
|
47
69
|
return {
|
|
48
70
|
status: cachedResult,
|
|
49
71
|
nodePath: {
|
|
@@ -59,6 +81,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, key
|
|
|
59
81
|
const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromFilenameByLine)({
|
|
60
82
|
fileName,
|
|
61
83
|
line,
|
|
84
|
+
componentIdentity,
|
|
62
85
|
keys,
|
|
63
86
|
effects,
|
|
64
87
|
remotionRoot,
|
|
@@ -66,13 +89,14 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, key
|
|
|
66
89
|
});
|
|
67
90
|
return status;
|
|
68
91
|
};
|
|
69
|
-
const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, keys, effects, remotionRoot, clientId, logLevel, }) => {
|
|
92
|
+
const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, }) => {
|
|
70
93
|
var _a;
|
|
71
94
|
const initialResult = getSequencePropsStatus({
|
|
72
95
|
fileName,
|
|
73
96
|
line,
|
|
74
97
|
column,
|
|
75
98
|
preferredNodePath,
|
|
99
|
+
componentIdentity,
|
|
76
100
|
keys,
|
|
77
101
|
effects,
|
|
78
102
|
remotionRoot,
|
|
@@ -105,6 +129,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
105
129
|
const result = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
|
|
106
130
|
fileContents: event.content,
|
|
107
131
|
nodePath: nodePath.nodePath,
|
|
132
|
+
componentIdentity,
|
|
108
133
|
keys,
|
|
109
134
|
effects,
|
|
110
135
|
});
|
|
@@ -125,7 +150,8 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
125
150
|
});
|
|
126
151
|
}
|
|
127
152
|
catch (error) {
|
|
128
|
-
if (error instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError
|
|
153
|
+
if (error instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError ||
|
|
154
|
+
error instanceof jsx_component_identity_1.JsxElementIdentityMismatchError) {
|
|
129
155
|
(0, live_events_1.waitForLiveEventsListener)().then((listener) => {
|
|
130
156
|
listener.sendEventToClientId(clientId, {
|
|
131
157
|
type: 'lost-node-path',
|
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.
|
|
6
|
+
"version": "4.0.477",
|
|
7
7
|
"description": "Run a Remotion Studio with a server backend",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -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.
|
|
30
|
+
"remotion": "4.0.477",
|
|
31
31
|
"recast": "0.23.11",
|
|
32
|
-
"@remotion/bundler": "4.0.
|
|
33
|
-
"@remotion/renderer": "4.0.
|
|
34
|
-
"@remotion/studio-shared": "4.0.
|
|
32
|
+
"@remotion/bundler": "4.0.477",
|
|
33
|
+
"@remotion/renderer": "4.0.477",
|
|
34
|
+
"@remotion/studio-shared": "4.0.477",
|
|
35
35
|
"memfs": "3.4.3",
|
|
36
36
|
"open": "8.4.2"
|
|
37
37
|
},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"ast-types": "0.16.1",
|
|
40
40
|
"react": "19.2.3",
|
|
41
41
|
"@types/semver": "7.5.3",
|
|
42
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
42
|
+
"@remotion/eslint-config-internal": "4.0.477",
|
|
43
43
|
"eslint": "9.19.0",
|
|
44
44
|
"@types/node": "20.12.14",
|
|
45
45
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|