@remotion/studio-server 4.0.490 → 4.0.491

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 (43) hide show
  1. package/dist/better-opn/index.d.ts +4 -0
  2. package/dist/better-opn/index.js +152 -31
  3. package/dist/codemods/paste-effects.d.ts +2 -1
  4. package/dist/codemods/paste-effects.js +33 -6
  5. package/dist/codemods/update-keyframes/update-keyframes.d.ts +9 -5
  6. package/dist/codemods/update-keyframes/update-keyframes.js +88 -42
  7. package/dist/codemods/update-nested-prop.d.ts +3 -2
  8. package/dist/codemods/update-nested-prop.js +17 -4
  9. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +6 -3
  10. package/dist/codemods/update-sequence-props/update-sequence-props.js +51 -10
  11. package/dist/helpers/video-config-numeric-expression.d.ts +12 -0
  12. package/dist/helpers/video-config-numeric-expression.js +152 -0
  13. package/dist/helpers/video-config-values.d.ts +7 -0
  14. package/dist/helpers/video-config-values.js +84 -0
  15. package/dist/index.d.ts +1 -2
  16. package/dist/preview-server/element-install-state.d.ts +1 -0
  17. package/dist/preview-server/routes/add-effect-keyframe.js +6 -0
  18. package/dist/preview-server/routes/add-keyframes.js +2 -0
  19. package/dist/preview-server/routes/add-sequence-keyframe.js +2 -0
  20. package/dist/preview-server/routes/apply-codemod.d.ts +1 -0
  21. package/dist/preview-server/routes/apply-codemod.js +62 -13
  22. package/dist/preview-server/routes/can-update-effect-props.d.ts +8 -4
  23. package/dist/preview-server/routes/can-update-effect-props.js +26 -5
  24. package/dist/preview-server/routes/can-update-sequence-props.d.ts +9 -5
  25. package/dist/preview-server/routes/can-update-sequence-props.js +71 -30
  26. package/dist/preview-server/routes/delete-keyframes.js +8 -0
  27. package/dist/preview-server/routes/move-keyframes.js +2 -0
  28. package/dist/preview-server/routes/paste-effects.js +2 -1
  29. package/dist/preview-server/routes/save-effect-props.js +5 -0
  30. package/dist/preview-server/routes/save-sequence-props.js +4 -0
  31. package/dist/preview-server/routes/subscribe-to-sequence-props.js +2 -1
  32. package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +1 -0
  33. package/dist/preview-server/routes/update-effect-keyframe-settings.js +6 -0
  34. package/dist/preview-server/routes/update-element-install-target.js +15 -1
  35. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +2 -0
  36. package/dist/preview-server/sequence-props-watchers.d.ts +5 -3
  37. package/dist/preview-server/sequence-props-watchers.js +14 -5
  38. package/dist/preview-server/start-server.d.ts +0 -1
  39. package/dist/preview-server/start-server.js +0 -1
  40. package/dist/routes.js +2 -0
  41. package/dist/start-studio.d.ts +1 -2
  42. package/dist/start-studio.js +1 -2
  43. package/package.json +6 -6
@@ -44,12 +44,17 @@ 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 parse_keyframe_easing_expression_1 = require("../../helpers/parse-keyframe-easing-expression");
46
46
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
47
+ const video_config_numeric_expression_1 = require("../../helpers/video-config-numeric-expression");
48
+ const video_config_values_1 = require("../../helpers/video-config-values");
47
49
  const jsx_component_identity_1 = require("../jsx-component-identity");
48
50
  const jsx_element_not_found_at_location_error_1 = require("../jsx-element-not-found-at-location-error");
49
51
  const can_update_effect_props_1 = require("./can-update-effect-props");
50
- const staticStatus = (codeValue) => ({
52
+ const staticStatus = (codeValue, numericExpression) => ({
51
53
  status: 'static',
52
54
  codeValue,
55
+ ...(numericExpression === null || numericExpression.type === 'literal'
56
+ ? {}
57
+ : { numericExpression }),
53
58
  });
54
59
  const computedStatus = () => ({
55
60
  status: 'computed',
@@ -341,9 +346,9 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
341
346
  output,
342
347
  };
343
348
  };
344
- const getInterpolationKeyframes = (node, ast) => {
349
+ const getInterpolationKeyframes = (node, ast, videoConfigValues) => {
345
350
  if (node.type === 'TSAsExpression') {
346
- return getInterpolationKeyframes(node.expression, ast);
351
+ return getInterpolationKeyframes(node.expression, ast, videoConfigValues);
347
352
  }
348
353
  if (node.type === 'CallExpression' &&
349
354
  node.callee.type === 'Identifier' &&
@@ -352,7 +357,7 @@ const getInterpolationKeyframes = (node, ast) => {
352
357
  node.arguments[0].type !== 'ArgumentPlaceholder' &&
353
358
  node.arguments[0].type !== 'JSXNamespacedName' &&
354
359
  node.arguments[0].type !== 'SpreadElement') {
355
- const interpolation = getInterpolationKeyframes(node.arguments[0], ast);
360
+ const interpolation = getInterpolationKeyframes(node.arguments[0], ast, videoConfigValues);
356
361
  if (!interpolation) {
357
362
  return undefined;
358
363
  }
@@ -398,13 +403,17 @@ const getInterpolationKeyframes = (node, ast) => {
398
403
  outputElement.type === 'SpreadElement') {
399
404
  return undefined;
400
405
  }
401
- const frame = getNumericValue(inputElement);
402
- if (frame === null || !(0, exports.isStaticValue)(outputElement)) {
406
+ const frameExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
407
+ node: inputElement,
408
+ videoConfigValues,
409
+ });
410
+ if (frameExpression === null || !(0, exports.isStaticValue)(outputElement)) {
403
411
  return undefined;
404
412
  }
405
413
  keyframes.push({
406
- frame,
414
+ frame: frameExpression.value,
407
415
  value: (0, exports.extractStaticValue)(outputElement),
416
+ ...(frameExpression.type === 'literal' ? {} : { frameExpression }),
408
417
  });
409
418
  }
410
419
  if (keyframes.length === 0) {
@@ -455,8 +464,8 @@ const isCurrentFrameIdentifier = (node, ast) => {
455
464
  });
456
465
  return hasUseCurrentFrameDeclaration && !hasOtherDeclaration;
457
466
  };
458
- const getComputedStatus = (node, ast) => {
459
- const interpolation = getInterpolationKeyframes(node, ast);
467
+ const getComputedStatus = (node, ast, videoConfigValues) => {
468
+ const interpolation = getInterpolationKeyframes(node, ast, videoConfigValues);
460
469
  if (!interpolation) {
461
470
  return computedStatus();
462
471
  }
@@ -471,7 +480,7 @@ const getComputedStatus = (node, ast) => {
471
480
  };
472
481
  };
473
482
  exports.getComputedStatus = getComputedStatus;
474
- const getPropsStatus = (jsxElement, ast) => {
483
+ const getPropsStatus = (jsxElement, ast, videoConfigValues) => {
475
484
  const props = {};
476
485
  for (const attr of jsxElement.attributes) {
477
486
  if (attr.type === 'JSXSpreadAttribute') {
@@ -486,11 +495,11 @@ const getPropsStatus = (jsxElement, ast) => {
486
495
  }
487
496
  const { value } = attr;
488
497
  if (!value) {
489
- props[name] = staticStatus(true);
498
+ props[name] = staticStatus(true, null);
490
499
  continue;
491
500
  }
492
501
  if (value.type === 'StringLiteral') {
493
- props[name] = staticStatus(value.value);
502
+ props[name] = staticStatus(value.value, null);
494
503
  continue;
495
504
  }
496
505
  if (value.type === 'JSXExpressionContainer') {
@@ -500,10 +509,16 @@ const getPropsStatus = (jsxElement, ast) => {
500
509
  continue;
501
510
  }
502
511
  if (!(0, exports.isStaticValue)(expression)) {
503
- props[name] = (0, exports.getComputedStatus)(expression, ast);
512
+ const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
513
+ node: expression,
514
+ videoConfigValues,
515
+ });
516
+ props[name] = numericExpression
517
+ ? staticStatus(numericExpression.value, numericExpression)
518
+ : (0, exports.getComputedStatus)(expression, ast, videoConfigValues);
504
519
  continue;
505
520
  }
506
- props[name] = staticStatus((0, exports.extractStaticValue)(expression));
521
+ props[name] = staticStatus((0, exports.extractStaticValue)(expression), null);
507
522
  continue;
508
523
  }
509
524
  props[name] = computedStatus();
@@ -651,13 +666,13 @@ const validateStyleValue = (childKey, value) => {
651
666
  }
652
667
  return true;
653
668
  };
654
- const getNestedPropStatus = (jsxElement, ast, parentKey, childKey) => {
669
+ const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfigValues, }) => {
655
670
  const attr = jsxElement.attributes.find((a) => a.type !== 'JSXSpreadAttribute' &&
656
671
  a.name.type !== 'JSXNamespacedName' &&
657
672
  a.name.name === parentKey);
658
673
  if (!attr || !attr.value) {
659
674
  // Parent attribute doesn't exist, nested prop can be added
660
- return staticStatus(undefined);
675
+ return staticStatus(undefined, null);
661
676
  }
662
677
  if (attr.value.type !== 'JSXExpressionContainer') {
663
678
  return computedStatus();
@@ -674,34 +689,41 @@ const getNestedPropStatus = (jsxElement, ast, parentKey, childKey) => {
674
689
  (p.key.type === 'StringLiteral' && p.key.value === childKey)));
675
690
  if (!prop) {
676
691
  // Property not set in the object, can be added
677
- return staticStatus(undefined);
692
+ return staticStatus(undefined, null);
678
693
  }
679
694
  const propValue = prop.value;
680
695
  if (!(0, exports.isStaticValue)(propValue)) {
681
- return (0, exports.getComputedStatus)(propValue, ast);
696
+ const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
697
+ node: propValue,
698
+ videoConfigValues,
699
+ });
700
+ return numericExpression
701
+ ? staticStatus(numericExpression.value, numericExpression)
702
+ : (0, exports.getComputedStatus)(propValue, ast, videoConfigValues);
682
703
  }
683
704
  const propStatus = (0, exports.extractStaticValue)(propValue);
684
705
  if (!validateStyleValue(childKey, propStatus)) {
685
706
  return computedStatus();
686
707
  }
687
- return staticStatus(propStatus);
708
+ return staticStatus(propStatus, null);
688
709
  };
689
- const computeEffectsForJsx = ({ ast, jsxElement, effects, }) => {
710
+ const computeEffectsForJsx = ({ ast, jsxElement, effects, videoConfigValues, }) => {
690
711
  return effects.map((effect, effectIndex) => (0, can_update_effect_props_1.computeEffectPropStatus)({
691
712
  ast,
692
713
  jsx: jsxElement,
693
714
  effectIndex,
694
715
  keys: effect,
716
+ videoConfigValues,
695
717
  }));
696
718
  };
697
- const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys, }) => {
698
- const allProps = getPropsStatus(jsxElement, ast);
719
+ const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys, videoConfigValues, }) => {
720
+ const allProps = getPropsStatus(jsxElement, ast, videoConfigValues);
699
721
  const filteredProps = {};
700
722
  for (const key of keys) {
701
723
  if (key === 'children') {
702
724
  const staticChildrenAttribute = (0, exports.getStaticJsxChildrenAttribute)(jsxElement);
703
725
  if (staticChildrenAttribute) {
704
- filteredProps[key] = staticStatus(staticChildrenAttribute.value);
726
+ filteredProps[key] = staticStatus(staticChildrenAttribute.value, null);
705
727
  continue;
706
728
  }
707
729
  if ((0, exports.hasJsxChildrenAttribute)(jsxElement)) {
@@ -710,26 +732,36 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys,
710
732
  }
711
733
  const staticTextContent = (0, exports.getStaticJsxTextContent)(jsxElementNode);
712
734
  filteredProps[key] = staticTextContent
713
- ? staticStatus(staticTextContent.value)
735
+ ? staticStatus(staticTextContent.value, null)
714
736
  : computedStatus();
715
737
  continue;
716
738
  }
717
739
  const dotIndex = key.indexOf('.');
718
740
  if (dotIndex !== -1) {
719
- filteredProps[key] = getNestedPropStatus(jsxElement, ast, key.slice(0, dotIndex), key.slice(dotIndex + 1));
741
+ filteredProps[key] = getNestedPropStatus({
742
+ jsxElement,
743
+ ast,
744
+ parentKey: key.slice(0, dotIndex),
745
+ childKey: key.slice(dotIndex + 1),
746
+ videoConfigValues,
747
+ });
720
748
  }
721
749
  else if (key in allProps) {
722
750
  filteredProps[key] = allProps[key];
723
751
  }
724
752
  else {
725
- filteredProps[key] = staticStatus(undefined);
753
+ filteredProps[key] = staticStatus(undefined, null);
726
754
  }
727
755
  }
728
756
  return filteredProps;
729
757
  };
730
- const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, effects, }) => {
758
+ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, effects, videoConfigValues, }) => {
731
759
  var _a;
732
760
  const ast = (0, parse_ast_1.parseAst)(fileContents);
761
+ const videoConfigIdentifierValues = (0, video_config_values_1.getVideoConfigIdentifierValues)({
762
+ ast,
763
+ videoConfigValues,
764
+ });
733
765
  const jsxElementNode = (0, exports.findJsxElementNodeAtNodePath)(ast, nodePath);
734
766
  const jsxElement = (_a = jsxElementNode === null || jsxElementNode === void 0 ? void 0 : jsxElementNode.openingElement) !== null && _a !== void 0 ? _a : null;
735
767
  if (!jsxElement || !jsxElementNode) {
@@ -746,8 +778,14 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, compone
746
778
  jsxElementNode,
747
779
  ast,
748
780
  keys,
781
+ videoConfigValues: videoConfigIdentifierValues,
782
+ });
783
+ const effectsStatuses = computeEffectsForJsx({
784
+ ast,
785
+ jsxElement,
786
+ effects,
787
+ videoConfigValues: videoConfigIdentifierValues,
749
788
  });
750
- const effectsStatuses = computeEffectsForJsx({ ast, jsxElement, effects });
751
789
  return {
752
790
  canUpdate: true,
753
791
  props: filteredProps,
@@ -755,7 +793,7 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, compone
755
793
  };
756
794
  };
757
795
  exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
758
- const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, }) => {
796
+ const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, videoConfigValues, }) => {
759
797
  const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
760
798
  remotionRoot,
761
799
  fileName,
@@ -768,10 +806,11 @@ const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, key
768
806
  componentIdentity,
769
807
  keys,
770
808
  effects,
809
+ videoConfigValues,
771
810
  });
772
811
  };
773
812
  exports.computeSequencePropsStatus = computeSequencePropsStatus;
774
- const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, }) => {
813
+ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, videoConfigValues, }) => {
775
814
  try {
776
815
  const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
777
816
  remotionRoot,
@@ -798,12 +837,14 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
798
837
  keys,
799
838
  effects,
800
839
  remotionRoot,
840
+ videoConfigValues,
801
841
  }),
802
842
  nodePath: {
803
843
  absolutePath,
804
844
  nodePath: resolvedNodePath,
805
845
  sequenceKeys: keys,
806
846
  effectKeys: effects,
847
+ videoConfigValues,
807
848
  },
808
849
  success: true,
809
850
  };
@@ -8,6 +8,7 @@ const parse_ast_1 = require("../../codemods/parse-ast");
8
8
  const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
9
9
  const file_watcher_1 = require("../../file-watcher");
10
10
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
11
+ const video_config_values_1 = require("../../helpers/video-config-values");
11
12
  const undo_stack_1 = require("../undo-stack");
12
13
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
13
14
  const can_update_effect_props_1 = require("./can-update-effect-props");
@@ -95,6 +96,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
95
96
  const result = await (0, update_keyframes_1.updateSequenceKeyframes)({
96
97
  input: output,
97
98
  nodePath: firstSequenceKeyframe.nodePath.nodePath,
99
+ videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
98
100
  updates: keyframeGroup.map((keyframe) => ({
99
101
  key: keyframe.key,
100
102
  operation: {
@@ -125,6 +127,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
125
127
  input: output,
126
128
  sequenceNodePath: firstEffectKeyframe.sequenceNodePath.nodePath,
127
129
  effectIndex: firstEffectKeyframe.effectIndex,
130
+ videoConfigValues: firstEffectKeyframe.sequenceNodePath.videoConfigValues,
128
131
  updates: keyframeGroup.map((keyframe) => ({
129
132
  key: keyframe.key,
130
133
  operation: {
@@ -217,6 +220,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
217
220
  nodePath: keyframe.nodePath.nodePath,
218
221
  componentIdentity: null,
219
222
  effects: [],
223
+ videoConfigValues: keyframe.nodePath.videoConfigValues,
220
224
  });
221
225
  return {
222
226
  fileName: keyframe.fileName,
@@ -246,6 +250,10 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
246
250
  jsx,
247
251
  effectIndex: keyframe.effectIndex,
248
252
  keys: (0, studio_shared_1.getAllSchemaKeys)(keyframe.schema),
253
+ videoConfigValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
254
+ ast,
255
+ videoConfigValues: keyframe.sequenceNodePath.videoConfigValues,
256
+ }),
249
257
  });
250
258
  });
251
259
  return { sequenceResults, effectResults };
@@ -111,6 +111,7 @@ const moveKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, rem
111
111
  input: output,
112
112
  nodePath: firstSequenceKeyframe.nodePath.nodePath,
113
113
  schema: firstSequenceKeyframe.schema,
114
+ videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
114
115
  updates,
115
116
  });
116
117
  output = result.output;
@@ -152,6 +153,7 @@ const moveKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, rem
152
153
  sequenceNodePath: firstEffectKeyframe.sequenceNodePath.nodePath,
153
154
  effectIndex: firstEffectKeyframe.effectIndex,
154
155
  schema: firstEffectKeyframe.schema,
156
+ videoConfigValues: firstEffectKeyframe.sequenceNodePath.videoConfigValues,
155
157
  updates,
156
158
  });
157
159
  output = result.output;
@@ -17,7 +17,7 @@ const getPastedEffectDescription = (effectLabels) => {
17
17
  }
18
18
  return `${effectLabels.length} effects`;
19
19
  };
20
- const pasteEffectsHandler = ({ input: { targetFileName, targetSequenceNodePath, type, effects, clientId }, remotionRoot, logLevel, }) => {
20
+ const pasteEffectsHandler = ({ input: { targetFileName, targetSequenceNodePath, type, effects, clientId, insertAtIndices, }, remotionRoot, logLevel, }) => {
21
21
  return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
22
22
  try {
23
23
  if (effects.length === 0 && type !== 'effects-replacing') {
@@ -36,6 +36,7 @@ const pasteEffectsHandler = ({ input: { targetFileName, targetSequenceNodePath,
36
36
  targetSequenceNodePath: targetSequenceNodePath.nodePath,
37
37
  type,
38
38
  effects,
39
+ insertAtIndices,
39
40
  });
40
41
  const effectDescription = getPastedEffectDescription(effectLabels);
41
42
  (0, undo_stack_1.pushToUndoStack)({
@@ -8,6 +8,7 @@ const parse_ast_1 = require("../../codemods/parse-ast");
8
8
  const update_effect_props_1 = require("../../codemods/update-effect-props/update-effect-props");
9
9
  const file_watcher_1 = require("../../file-watcher");
10
10
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
11
+ const video_config_values_1 = require("../../helpers/video-config-values");
11
12
  const undo_stack_1 = require("../undo-stack");
12
13
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
13
14
  const can_update_effect_props_1 = require("./can-update-effect-props");
@@ -122,6 +123,10 @@ const saveEffectPropsHandler = ({ input, remotionRoot, logLevel }) => (0, source
122
123
  jsx,
123
124
  effectIndex,
124
125
  keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
126
+ videoConfigValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
127
+ ast,
128
+ videoConfigValues: sequenceNodePath.videoConfigValues,
129
+ }),
125
130
  });
126
131
  });
127
132
  exports.saveEffectPropsHandler = saveEffectPropsHandler;
@@ -50,6 +50,7 @@ const convertSequencePropEditToCodemodChange = (edit) => {
50
50
  },
51
51
  ],
52
52
  schema: edit.schema,
53
+ videoConfigValues: edit.nodePath.videoConfigValues,
53
54
  };
54
55
  };
55
56
  exports.convertSequencePropEditToCodemodChange = convertSequencePropEditToCodemodChange;
@@ -182,6 +183,7 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
182
183
  input: output,
183
184
  nodePath: firstSequenceKeyframe.nodePath.nodePath,
184
185
  schema: firstSequenceKeyframe.schema,
186
+ videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
185
187
  updates,
186
188
  });
187
189
  output = result.output;
@@ -223,6 +225,7 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
223
225
  sequenceNodePath: firstEffectKeyframe.sequenceNodePath.nodePath,
224
226
  effectIndex: firstEffectKeyframe.effectIndex,
225
227
  schema: firstEffectKeyframe.schema,
228
+ videoConfigValues: firstEffectKeyframe.sequenceNodePath.videoConfigValues,
226
229
  updates,
227
230
  });
228
231
  output = result.output;
@@ -331,6 +334,7 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
331
334
  nodePath: edit.nodePath.nodePath,
332
335
  componentIdentity: null,
333
336
  effects: [],
337
+ videoConfigValues: edit.nodePath.videoConfigValues,
334
338
  });
335
339
  return {
336
340
  fileName: edit.fileName,
@@ -2,7 +2,7 @@
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, componentIdentity, keys, effects, clientId, }, remotionRoot, logLevel, }) => {
5
+ const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, componentIdentity, keys, effects, clientId, videoConfigValues, }, remotionRoot, logLevel, }) => {
6
6
  const result = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
7
7
  fileName,
8
8
  line,
@@ -13,6 +13,7 @@ const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, c
13
13
  effects,
14
14
  remotionRoot,
15
15
  clientId,
16
+ videoConfigValues,
16
17
  logLevel,
17
18
  });
18
19
  return Promise.resolve(result);
@@ -10,6 +10,7 @@ const unsubscribeFromSequenceProps = ({ input: { fileName, nodePath, clientId, s
10
10
  clientId,
11
11
  sequenceKeys,
12
12
  effectKeys,
13
+ videoConfigValues: nodePath.videoConfigValues,
13
14
  });
14
15
  return Promise.resolve(undefined);
15
16
  };
@@ -8,6 +8,7 @@ const parse_ast_1 = require("../../codemods/parse-ast");
8
8
  const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
9
9
  const file_watcher_1 = require("../../file-watcher");
10
10
  const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
11
+ const video_config_values_1 = require("../../helpers/video-config-values");
11
12
  const undo_stack_1 = require("../undo-stack");
12
13
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
13
14
  const can_update_effect_props_1 = require("./can-update-effect-props");
@@ -27,6 +28,7 @@ const updateEffectKeyframeSettingsHandler = ({ input: { fileName, sequenceNodePa
27
28
  sequenceNodePath: sequenceNodePath.nodePath,
28
29
  effectIndex,
29
30
  schema,
31
+ videoConfigValues: sequenceNodePath.videoConfigValues,
30
32
  updates: [
31
33
  {
32
34
  key,
@@ -92,6 +94,10 @@ const updateEffectKeyframeSettingsHandler = ({ input: { fileName, sequenceNodePa
92
94
  jsx,
93
95
  effectIndex,
94
96
  keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
97
+ videoConfigValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
98
+ ast,
99
+ videoConfigValues: sequenceNodePath.videoConfigValues,
100
+ }),
95
101
  });
96
102
  });
97
103
  exports.updateEffectKeyframeSettingsHandler = updateEffectKeyframeSettingsHandler;
@@ -5,7 +5,7 @@ const element_install_state_1 = require("../element-install-state");
5
5
  const isFiniteTimestamp = (value) => {
6
6
  return value === null || (Number.isFinite(value) && value > 0);
7
7
  };
8
- const updateElementInstallTargetHandler = ({ input }) => {
8
+ const updateElementInstallTargetHandler = ({ input, request }) => {
9
9
  if (typeof input.clientId !== 'string' || input.clientId.length === 0) {
10
10
  throw new Error('Invalid client ID');
11
11
  }
@@ -22,6 +22,20 @@ const updateElementInstallTargetHandler = ({ input }) => {
22
22
  if (input.compositionId !== null && typeof input.compositionId !== 'string') {
23
23
  throw new Error('Invalid composition ID');
24
24
  }
25
+ if (typeof input.studioUrl !== 'string') {
26
+ throw new Error('Invalid Studio URL');
27
+ }
28
+ let studioUrl;
29
+ try {
30
+ studioUrl = new URL(input.studioUrl);
31
+ }
32
+ catch (_a) {
33
+ throw new Error('Invalid Studio URL');
34
+ }
35
+ if (typeof request.headers.origin !== 'string' ||
36
+ studioUrl.origin !== request.headers.origin) {
37
+ throw new Error('Studio URL must match the request origin');
38
+ }
25
39
  (0, element_install_state_1.updateElementInstallTarget)(input);
26
40
  return Promise.resolve({});
27
41
  };
@@ -24,6 +24,7 @@ const updateSequenceKeyframeSettingsHandler = ({ input: { fileName, nodePath, ke
24
24
  input: fileContents,
25
25
  nodePath: nodePath.nodePath,
26
26
  schema,
27
+ videoConfigValues: nodePath.videoConfigValues,
27
28
  updates: [
28
29
  {
29
30
  key,
@@ -80,6 +81,7 @@ const updateSequenceKeyframeSettingsHandler = ({ input: { fileName, nodePath, ke
80
81
  nodePath: updatedNodePath,
81
82
  componentIdentity: null,
82
83
  effects: [],
84
+ videoConfigValues: nodePath.videoConfigValues,
83
85
  });
84
86
  const updatedSubscriptionKey = { ...nodePath, nodePath: updatedNodePath };
85
87
  return {
@@ -1,6 +1,6 @@
1
1
  import { type SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
2
- import type { SequenceNodePath } from 'remotion';
3
- export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, }: {
2
+ import type { SequenceNodePath, VideoConfigValues } from 'remotion';
3
+ export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }: {
4
4
  fileName: string;
5
5
  line: number;
6
6
  column: number;
@@ -11,13 +11,15 @@ export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column
11
11
  remotionRoot: string;
12
12
  clientId: string;
13
13
  logLevel: "error" | "info" | "trace" | "verbose" | "warn";
14
+ videoConfigValues: VideoConfigValues;
14
15
  }) => SubscribeToSequencePropsResponse;
15
- export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, }: {
16
+ export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, videoConfigValues, }: {
16
17
  fileName: string;
17
18
  nodePath: SequenceNodePath;
18
19
  remotionRoot: string;
19
20
  clientId: string;
20
21
  sequenceKeys: string[];
21
22
  effectKeys: string[][];
23
+ videoConfigValues: VideoConfigValues | null;
22
24
  }) => void;
23
25
  export declare const unsubscribeClientSequencePropsWatchers: (clientId: string) => void;
@@ -14,7 +14,8 @@ const live_events_1 = require("./live-events");
14
14
  const node_path_cache_1 = require("./node-path-cache");
15
15
  const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
16
16
  const sequencePropsWatchers = {};
17
- const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, componentIdentity, keys, effects, remotionRoot, logLevel, }) => {
17
+ const getWatcherKey = (nodePath) => `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath)}:${JSON.stringify(nodePath.videoConfigValues)}`;
18
+ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, componentIdentity, keys, effects, remotionRoot, logLevel, videoConfigValues, }) => {
18
19
  if (preferredNodePath) {
19
20
  try {
20
21
  const fromNodePath = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
@@ -24,6 +25,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
24
25
  keys,
25
26
  effects,
26
27
  remotionRoot,
28
+ videoConfigValues,
27
29
  });
28
30
  return {
29
31
  status: fromNodePath,
@@ -32,6 +34,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
32
34
  nodePath: preferredNodePath,
33
35
  sequenceKeys: keys,
34
36
  effectKeys: effects,
37
+ videoConfigValues,
35
38
  },
36
39
  success: true,
37
40
  };
@@ -55,6 +58,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
55
58
  keys,
56
59
  effects,
57
60
  remotionRoot,
61
+ videoConfigValues,
58
62
  });
59
63
  }
60
64
  catch (error) {
@@ -73,6 +77,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
73
77
  nodePath: cachedNodePath,
74
78
  sequenceKeys: keys,
75
79
  effectKeys: effects,
80
+ videoConfigValues,
76
81
  },
77
82
  success: true,
78
83
  };
@@ -86,10 +91,11 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
86
91
  effects,
87
92
  remotionRoot,
88
93
  logLevel,
94
+ videoConfigValues,
89
95
  });
90
96
  return status;
91
97
  };
92
- const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, }) => {
98
+ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }) => {
93
99
  var _a;
94
100
  const initialResult = getSequencePropsStatus({
95
101
  fileName,
@@ -101,6 +107,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
101
107
  effects,
102
108
  remotionRoot,
103
109
  logLevel,
110
+ videoConfigValues,
104
111
  });
105
112
  if (!initialResult.success) {
106
113
  return initialResult;
@@ -109,7 +116,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
109
116
  // Cache the resolved nodePath for future lookups with stale source maps
110
117
  (0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath.nodePath);
111
118
  const { nodePath } = initialResult;
112
- const watcherKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
119
+ const watcherKey = getWatcherKey(nodePath);
113
120
  // If a watcher already exists for this key, just bump the ref count
114
121
  if ((_a = sequencePropsWatchers[clientId]) === null || _a === void 0 ? void 0 : _a[watcherKey]) {
115
122
  sequencePropsWatchers[clientId][watcherKey].refCount++;
@@ -132,6 +139,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
132
139
  componentIdentity,
133
140
  keys,
134
141
  effects,
142
+ videoConfigValues,
135
143
  });
136
144
  const previousEffectChain = result.effects.map((effect) => effect.canUpdate && effect.callee);
137
145
  const newEffectChain = initialResult.success &&
@@ -173,13 +181,14 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
173
181
  return initialResult;
174
182
  };
175
183
  exports.subscribeToSequencePropsWatchers = subscribeToSequencePropsWatchers;
176
- const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, }) => {
184
+ const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, videoConfigValues, }) => {
177
185
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
178
- const watcherKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)({
186
+ const watcherKey = getWatcherKey({
179
187
  absolutePath,
180
188
  nodePath,
181
189
  sequenceKeys,
182
190
  effectKeys,
191
+ videoConfigValues,
183
192
  });
184
193
  if (!sequencePropsWatchers[clientId] ||
185
194
  !sequencePropsWatchers[clientId][watcherKey]) {
@@ -22,7 +22,6 @@ export declare const startServer: (options: {
22
22
  bufferStateDelayInMilliseconds: number | null;
23
23
  remotionRoot: string;
24
24
  keyboardShortcutsEnabled: boolean;
25
- experimentalClientSideRenderingEnabled: boolean;
26
25
  publicDir: string;
27
26
  poll: number | null;
28
27
  staticHash: string;
@@ -41,7 +41,6 @@ const startServer = async (options) => {
41
41
  maxTimelineTracks: (_c = options === null || options === void 0 ? void 0 : options.maxTimelineTracks) !== null && _c !== void 0 ? _c : null,
42
42
  remotionRoot: options.remotionRoot,
43
43
  keyboardShortcutsEnabled: options.keyboardShortcutsEnabled,
44
- experimentalClientSideRenderingEnabled: options.experimentalClientSideRenderingEnabled,
45
44
  poll: options.poll,
46
45
  bufferStateDelayInMilliseconds: options.bufferStateDelayInMilliseconds,
47
46
  askAIEnabled: options.askAIEnabled,
package/dist/routes.js CHANGED
@@ -41,6 +41,7 @@ const node_url_1 = require("node:url");
41
41
  const bundler_1 = require("@remotion/bundler");
42
42
  const renderer_1 = require("@remotion/renderer");
43
43
  const studio_shared_1 = require("@remotion/studio-shared");
44
+ const better_opn_1 = require("./better-opn");
44
45
  const client_render_queue_1 = require("./client-render-queue");
45
46
  const get_file_source_1 = require("./helpers/get-file-source");
46
47
  const get_installed_installable_packages_1 = require("./helpers/get-installed-installable-packages");
@@ -215,6 +216,7 @@ const handleRequestElementInstall = async ({ liveEventsServer, request, response
215
216
  }));
216
217
  return;
217
218
  }
219
+ (0, better_opn_1.focusBrowserTab)({ url: target.studioUrl }).catch(() => undefined);
218
220
  response.writeHead(200);
219
221
  response.end(JSON.stringify({ success: true, status: 'sent' }));
220
222
  }