@remotion/studio 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 (140) hide show
  1. package/dist/Studio.js +2 -2
  2. package/dist/api/helpers/calc-new-props.js +5 -8
  3. package/dist/api/update-default-props.d.ts +7 -3
  4. package/dist/api/update-default-props.js +7 -21
  5. package/dist/api/visual-control.js +6 -0
  6. package/dist/components/DefaultPropsEditor.d.ts +8 -0
  7. package/dist/components/DefaultPropsEditor.js +15 -0
  8. package/dist/components/Editor.js +0 -14
  9. package/dist/components/EditorContexts.js +6 -3
  10. package/dist/components/KeyboardShortcutsExplainer.js +6 -2
  11. package/dist/components/MenuBuildIndicator.js +1 -0
  12. package/dist/components/MenuToolbar.js +3 -1
  13. package/dist/components/NewComposition/InputDragger.js +2 -2
  14. package/dist/components/NewComposition/RemTextarea.js +4 -0
  15. package/dist/components/ObserveDefaultPropsContext.d.ts +11 -0
  16. package/dist/components/ObserveDefaultPropsContext.js +120 -0
  17. package/dist/components/OptionsPanel.js +90 -28
  18. package/dist/components/RenderModal/CrfSetting.d.ts +1 -1
  19. package/dist/components/RenderModal/DataEditor.d.ts +4 -5
  20. package/dist/components/RenderModal/DataEditor.js +9 -111
  21. package/dist/components/RenderModal/RenderModalJSONPropsEditor.d.ts +1 -1
  22. package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +52 -48
  23. package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +0 -1
  24. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.d.ts +4 -9
  25. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +2 -61
  26. package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.d.ts +0 -1
  27. package/dist/components/RenderModal/SchemaEditor/SchemaErrorMessages.js +2 -3
  28. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.d.ts +0 -6
  29. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +2 -5
  30. package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.d.ts +3 -1
  31. package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.js +1 -1
  32. package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.d.ts +1 -6
  33. package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +15 -26
  34. package/dist/components/RenderModal/SchemaEditor/ZodArrayItemEditor.d.ts +0 -5
  35. package/dist/components/RenderModal/SchemaEditor/ZodArrayItemEditor.js +7 -12
  36. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.d.ts +0 -7
  37. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.js +5 -15
  38. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.d.ts +1 -6
  39. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +30 -28
  40. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.d.ts +1 -6
  41. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +13 -17
  42. package/dist/components/RenderModal/SchemaEditor/ZodDefaultEditor.d.ts +0 -5
  43. package/dist/components/RenderModal/SchemaEditor/ZodDefaultEditor.js +2 -2
  44. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.d.ts +1 -6
  45. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +13 -28
  46. package/dist/components/RenderModal/SchemaEditor/ZodEffectEditor.d.ts +1 -5
  47. package/dist/components/RenderModal/SchemaEditor/ZodEffectEditor.js +11 -12
  48. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.d.ts +1 -5
  49. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +12 -16
  50. package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.d.ts +2 -2
  51. package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.js +1 -2
  52. package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.d.ts +1 -6
  53. package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.js +20 -30
  54. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.d.ts +0 -2
  55. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +3 -6
  56. package/dist/components/RenderModal/SchemaEditor/ZodNullableEditor.d.ts +0 -5
  57. package/dist/components/RenderModal/SchemaEditor/ZodNullableEditor.js +2 -2
  58. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.d.ts +1 -6
  59. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +16 -21
  60. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.d.ts +2 -7
  61. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +27 -49
  62. package/dist/components/RenderModal/SchemaEditor/ZodOptionalEditor.d.ts +0 -5
  63. package/dist/components/RenderModal/SchemaEditor/ZodOptionalEditor.js +2 -2
  64. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.d.ts +1 -6
  65. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +8 -15
  66. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.d.ts +1 -6
  67. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +10 -15
  68. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.d.ts +1 -6
  69. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +13 -17
  70. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.d.ts +3 -6
  71. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +27 -27
  72. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.d.ts +0 -5
  73. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +45 -17
  74. package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.d.ts +1 -6
  75. package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +15 -26
  76. package/dist/components/RenderModal/SchemaEditor/ZodTupleItemEditor.d.ts +0 -5
  77. package/dist/components/RenderModal/SchemaEditor/ZodTupleItemEditor.js +4 -11
  78. package/dist/components/RenderModal/SchemaEditor/ZodUnionEditor.d.ts +0 -5
  79. package/dist/components/RenderModal/SchemaEditor/ZodUnionEditor.js +6 -6
  80. package/dist/components/RenderModal/ServerRenderModal.js +9 -3
  81. package/dist/components/RenderModal/WebRenderModal.js +9 -3
  82. package/dist/components/RenderModal/get-default-codecs.d.ts +5 -5
  83. package/dist/components/RenderModal/get-render-modal-warnings.d.ts +1 -2
  84. package/dist/components/RenderModal/get-render-modal-warnings.js +4 -6
  85. package/dist/components/RenderModal/human-readable-codec.d.ts +1 -1
  86. package/dist/components/RenderModal/human-readable-codec.js +3 -0
  87. package/dist/components/RenderModal/out-name-checker.d.ts +1 -1
  88. package/dist/components/RenderQueue/actions.d.ts +2 -3
  89. package/dist/components/RenderQueue/actions.js +1 -13
  90. package/dist/components/Timeline/Timeline.js +1 -1
  91. package/dist/components/Timeline/TimelineExpandedSection.js +7 -1
  92. package/dist/components/Timeline/TimelineFieldRow.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineFieldRow.js +25 -3
  94. package/dist/components/Timeline/TimelineImageInfo.d.ts +5 -0
  95. package/dist/components/Timeline/TimelineImageInfo.js +61 -0
  96. package/dist/components/Timeline/TimelineListItem.js +1 -2
  97. package/dist/components/Timeline/TimelineNumberField.js +4 -6
  98. package/dist/components/Timeline/TimelineRotationField.js +4 -6
  99. package/dist/components/Timeline/TimelineSequence.js +9 -4
  100. package/dist/components/Timeline/TimelineStack/index.js +3 -1
  101. package/dist/components/Timeline/TimelineTracks.js +1 -1
  102. package/dist/components/Timeline/TimelineTranslateField.js +28 -13
  103. package/dist/components/TopPanel.js +10 -5
  104. package/dist/components/UndoRedoButtons.d.ts +2 -0
  105. package/dist/components/UndoRedoButtons.js +116 -0
  106. package/dist/components/VisualControls/VisualControlHandle.js +18 -18
  107. package/dist/components/VisualControls/VisualControlsUndoSync.d.ts +2 -0
  108. package/dist/components/VisualControls/VisualControlsUndoSync.js +23 -0
  109. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +0 -1
  110. package/dist/esm/{chunk-ba0scebn.js → chunk-1x2ychmc.js} +4466 -5252
  111. package/dist/esm/index.mjs +25 -28
  112. package/dist/esm/internals.mjs +4466 -5252
  113. package/dist/esm/previewEntry.mjs +4652 -5497
  114. package/dist/esm/renderEntry.mjs +6 -6
  115. package/dist/helpers/client-id.js +13 -1
  116. package/dist/helpers/document-title.d.ts +0 -1
  117. package/dist/helpers/document-title.js +1 -17
  118. package/dist/helpers/render-modal-sections.d.ts +1 -1
  119. package/dist/helpers/timeline-layout.d.ts +1 -1
  120. package/dist/helpers/timeline-layout.js +1 -1
  121. package/dist/hot-middleware-client/client.d.ts +1 -6
  122. package/dist/hot-middleware-client/client.js +22 -73
  123. package/dist/hot-middleware-client/process-update.d.ts +0 -2
  124. package/dist/hot-middleware-client/process-update.js +6 -14
  125. package/dist/icons/redo.d.ts +3 -0
  126. package/dist/icons/redo.js +8 -0
  127. package/dist/icons/undo.d.ts +3 -0
  128. package/dist/icons/undo.js +8 -0
  129. package/dist/renderEntry.js +7 -6
  130. package/dist/visual-controls/VisualControls.js +9 -5
  131. package/dist/visual-controls/get-current-edited-value.js +5 -4
  132. package/dist/visual-controls/visual-control-store.d.ts +7 -0
  133. package/dist/visual-controls/visual-control-store.js +22 -0
  134. package/package.json +9 -9
  135. package/dist/components/GlobalPropsEditorUpdateButton.d.ts +0 -5
  136. package/dist/components/GlobalPropsEditorUpdateButton.js +0 -78
  137. package/dist/components/RenderModal/SchemaEditor/SchemaSaveButton.d.ts +0 -5
  138. package/dist/components/RenderModal/SchemaEditor/SchemaSaveButton.js +0 -18
  139. package/dist/components/RenderModal/SchemaEditor/local-state.d.ts +0 -25
  140. package/dist/components/RenderModal/SchemaEditor/local-state.js +0 -107
@@ -162,7 +162,7 @@ var renderContent = (Root) => {
162
162
  frameState: null,
163
163
  audioEnabled: window.remotion_audioEnabled,
164
164
  videoEnabled: window.remotion_videoEnabled,
165
- logLevel: window.remotion_logLevel,
165
+ logLevel: window.remotion_logLevel ?? "info",
166
166
  numberOfAudioTags: 0,
167
167
  audioLatencyHint: window.remotion_audioLatencyHint ?? "interactive",
168
168
  visualModeEnabled: false,
@@ -189,7 +189,7 @@ var renderContent = (Root) => {
189
189
  frameState: null,
190
190
  audioEnabled: window.remotion_audioEnabled,
191
191
  videoEnabled: window.remotion_videoEnabled,
192
- logLevel: window.remotion_logLevel,
192
+ logLevel: window.remotion_logLevel ?? "info",
193
193
  numberOfAudioTags: 0,
194
194
  audioLatencyHint: window.remotion_audioLatencyHint ?? "interactive",
195
195
  visualModeEnabled: false,
@@ -208,7 +208,7 @@ var renderContent = (Root) => {
208
208
  renderToDOM(/* @__PURE__ */ jsx("div", {
209
209
  children: /* @__PURE__ */ jsx(DelayedSpinner, {})
210
210
  }));
211
- import("./chunk-ba0scebn.js").then(({ StudioInternals }) => {
211
+ import("./chunk-1x2ychmc.js").then(({ StudioInternals }) => {
212
212
  window.remotion_isStudio = true;
213
213
  window.remotion_isReadOnlyStudio = true;
214
214
  window.remotion_inputProps = "{}";
@@ -252,14 +252,14 @@ if (typeof window !== "undefined") {
252
252
  const compositions = Internals.compositionsRef.current.getCompositions();
253
253
  const canSerializeDefaultProps = getCanSerializeDefaultProps(compositions);
254
254
  if (!canSerializeDefaultProps) {
255
- Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, "defaultProps are too big to serialize - trying to find the problematic composition...");
256
- Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, "Serialization:", compositions);
255
+ Internals.Log.warn({ logLevel: window.remotion_logLevel ?? "info", tag: null }, "defaultProps are too big to serialize - trying to find the problematic composition...");
256
+ Internals.Log.warn({ logLevel: window.remotion_logLevel ?? "info", tag: null }, "Serialization:", compositions);
257
257
  for (const comp of compositions) {
258
258
  if (!getCanSerializeDefaultProps(comp)) {
259
259
  throw new Error(`defaultProps too big - could not serialize - the defaultProps of composition with ID ${comp.id} - the object that was passed to defaultProps was too big. Learn how to mitigate this error by visiting https://remotion.dev/docs/troubleshooting/serialize-defaultprops`);
260
260
  }
261
261
  }
262
- Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, "Could not single out a problematic composition - The composition list as a whole is too big to serialize.");
262
+ Internals.Log.warn({ logLevel: window.remotion_logLevel ?? "info", tag: null }, "Could not single out a problematic composition - The composition list as a whole is too big to serialize.");
263
263
  throw new Error("defaultProps too big - Could not serialize - an object that was passed to defaultProps was too big. Learn how to mitigate this error by visiting https://remotion.dev/docs/troubleshooting/serialize-defaultprops");
264
264
  }
265
265
  return compositions;
@@ -63,7 +63,7 @@ const PreviewServerConnection = ({ children, readOnlyStudio }) => {
63
63
  const openEventSource = (0, react_1.useCallback)(() => {
64
64
  const source = new EventSource('/events');
65
65
  source.addEventListener('message', (event) => {
66
- var _a, _b;
66
+ var _a, _b, _c;
67
67
  const newEvent = JSON.parse(event.data);
68
68
  if (newEvent.type === 'new-input-props' ||
69
69
  newEvent.type === 'new-env-variables') {
@@ -74,6 +74,15 @@ const PreviewServerConnection = ({ children, readOnlyStudio }) => {
74
74
  type: 'connected',
75
75
  clientId: newEvent.clientId,
76
76
  });
77
+ listeners.current.forEach((l) => {
78
+ if (l.type === 'undo-redo-stack-changed') {
79
+ l.listener({
80
+ type: 'undo-redo-stack-changed',
81
+ undoFile: newEvent.undoFile,
82
+ redoFile: newEvent.redoFile,
83
+ });
84
+ }
85
+ });
77
86
  }
78
87
  if (newEvent.type === 'render-queue-updated') {
79
88
  (_a = context_1.renderJobsRef.current) === null || _a === void 0 ? void 0 : _a.updateRenderJobs(newEvent.queue);
@@ -99,6 +108,9 @@ const PreviewServerConnection = ({ children, readOnlyStudio }) => {
99
108
  detail: payload,
100
109
  }));
101
110
  }
111
+ if (newEvent.type === 'hmr') {
112
+ (_c = window.__remotion_processHmrEvent) === null || _c === void 0 ? void 0 : _c.call(window, newEvent.hmrEvent);
113
+ }
102
114
  listeners.current.forEach((l) => {
103
115
  if (l.type === newEvent.type) {
104
116
  l.listener(newEvent);
@@ -1,4 +1,3 @@
1
1
  import type { AnyRenderJob } from '../components/RenderQueue/context';
2
2
  export declare const setCurrentCanvasContentId: (id: string | null) => void;
3
- export declare const setUnsavedProps: (unsaved: boolean) => void;
4
3
  export declare const setRenderJobs: (jobs: AnyRenderJob[]) => void;
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setRenderJobs = exports.setUnsavedProps = exports.setCurrentCanvasContentId = void 0;
3
+ exports.setRenderJobs = exports.setCurrentCanvasContentId = void 0;
4
4
  const no_react_1 = require("remotion/no-react");
5
5
  const context_1 = require("../components/RenderQueue/context");
6
6
  let currentItemName = null;
7
- let unsavedProps = false;
8
- let tabInactive = false;
9
7
  let renderJobs = [];
10
8
  const setCurrentCanvasContentId = (id) => {
11
9
  if (!id) {
@@ -18,20 +16,11 @@ const setCurrentCanvasContentId = (id) => {
18
16
  updateTitle();
19
17
  };
20
18
  exports.setCurrentCanvasContentId = setCurrentCanvasContentId;
21
- const setUnsavedProps = (unsaved) => {
22
- window.remotion_unsavedProps = unsaved;
23
- unsavedProps = unsaved;
24
- };
25
- exports.setUnsavedProps = setUnsavedProps;
26
19
  const setRenderJobs = (jobs) => {
27
20
  renderJobs = jobs;
28
21
  updateTitle();
29
22
  };
30
23
  exports.setRenderJobs = setRenderJobs;
31
- document.addEventListener('visibilitychange', () => {
32
- tabInactive = document.visibilityState === 'hidden';
33
- updateTitle();
34
- });
35
24
  const productName = 'Remotion Studio';
36
25
  const suffix = `- ${productName}`;
37
26
  const updateTitle = () => {
@@ -42,7 +31,6 @@ const updateTitle = () => {
42
31
  const currentCompTitle = `${currentItemName} / ${window.remotion_projectName}`;
43
32
  document.title = [
44
33
  getProgressInBrackets(currentItemName, renderJobs),
45
- unsavedProps && tabInactive ? '✏️' : null,
46
34
  `${currentCompTitle} ${suffix}`,
47
35
  ]
48
36
  .filter(no_react_1.NoReactInternals.truthy)
@@ -70,7 +58,3 @@ const getProgressInBrackets = (selectedCompositionId, jobs) => {
70
58
  : `[${progInPercent}% ${currentRender.compositionId}]`;
71
59
  return progressInBrackets;
72
60
  };
73
- document.addEventListener('visibilitychange', () => {
74
- tabInactive = document.visibilityState === 'hidden';
75
- updateTitle();
76
- });
@@ -1,6 +1,6 @@
1
1
  import type { RenderType } from '../components/RenderModal/RenderModalAdvanced';
2
2
  type Section = 'general' | 'picture' | 'advanced' | 'data' | 'gif' | 'audio';
3
- export declare const useRenderModalSections: (renderMode: RenderType, codec: "aac" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => {
3
+ export declare const useRenderModalSections: (renderMode: RenderType, codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => {
4
4
  tab: Section;
5
5
  setTab: import("react").Dispatch<import("react").SetStateAction<Section>>;
6
6
  shownTabs: Section[];
@@ -16,4 +16,4 @@ export type SchemaFieldInfo = {
16
16
  };
17
17
  export declare const getSchemaFields: (controls: SequenceControls | null) => SchemaFieldInfo[] | null;
18
18
  export declare const getExpandedTrackHeight: (controls: SequenceControls | null) => number;
19
- export declare const getTimelineLayerHeight: (type: "other" | "video") => 25 | 50;
19
+ export declare const getTimelineLayerHeight: (type: "audio" | "image" | "other" | "sequence" | "video") => 25 | 50;
@@ -44,7 +44,7 @@ const getExpandedTrackHeight = (controls) => {
44
44
  };
45
45
  exports.getExpandedTrackHeight = getExpandedTrackHeight;
46
46
  const getTimelineLayerHeight = (type) => {
47
- if (type === 'video') {
47
+ if (type === 'video' || type === 'image') {
48
48
  return 50;
49
49
  }
50
50
  return 25;
@@ -4,15 +4,10 @@
4
4
  * and rewritten in TypeScript. This file is MIT licensed
5
5
  */
6
6
  import type { HotMiddlewareMessage } from '@remotion/studio-shared';
7
- declare function eventSourceWrapper(): {
8
- addMessageListener(fn: (msg: MessageEvent<any>) => void): void;
9
- };
10
7
  declare global {
11
8
  interface Window {
12
- __whmEventSourceWrapper: {
13
- [key: string]: ReturnType<typeof eventSourceWrapper>;
14
- };
15
9
  __webpack_hot_middleware_reporter__: Reporter;
10
+ __remotion_processHmrEvent?: (hmrEvent: HotMiddlewareMessage) => void;
16
11
  }
17
12
  }
18
13
  type Reporter = ReturnType<typeof createReporter>;
@@ -5,70 +5,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.enableHotMiddleware = void 0;
6
6
  const studio_shared_1 = require("@remotion/studio-shared");
7
7
  const process_update_1 = require("./process-update");
8
- function eventSourceWrapper() {
9
- let source;
10
- let lastActivity = Date.now();
11
- const listeners = [];
12
- init();
13
- const timer = setInterval(() => {
14
- if (Date.now() - lastActivity > studio_shared_1.hotMiddlewareOptions.timeout) {
15
- handleDisconnect();
16
- }
17
- }, studio_shared_1.hotMiddlewareOptions.timeout / 2);
18
- function init() {
19
- source = new window.EventSource(studio_shared_1.hotMiddlewareOptions.path);
20
- source.onopen = handleOnline;
21
- source.onerror = handleDisconnect;
22
- source.onmessage = handleMessage;
23
- }
24
- function handleOnline() {
25
- lastActivity = Date.now();
26
- }
27
- function handleMessage(event) {
28
- lastActivity = Date.now();
29
- for (let i = 0; i < listeners.length; i++) {
30
- listeners[i](event);
31
- }
32
- }
33
- function handleDisconnect() {
34
- clearInterval(timer);
35
- source.close();
36
- setTimeout(init, 1000);
37
- }
38
- return {
39
- addMessageListener(fn) {
40
- listeners.push(fn);
41
- },
42
- };
43
- }
44
- function getEventSourceWrapper() {
45
- if (!window.__whmEventSourceWrapper) {
46
- window.__whmEventSourceWrapper = {};
47
- }
48
- if (!window.__whmEventSourceWrapper[studio_shared_1.hotMiddlewareOptions.path]) {
49
- // cache the wrapper for other entries loaded on
50
- // the same page with the same hotMiddlewareOptions.path
51
- window.__whmEventSourceWrapper[studio_shared_1.hotMiddlewareOptions.path] =
52
- eventSourceWrapper();
53
- }
54
- return window.__whmEventSourceWrapper[studio_shared_1.hotMiddlewareOptions.path];
55
- }
56
- function connect() {
57
- getEventSourceWrapper().addMessageListener(handleMessage);
58
- function handleMessage(event) {
59
- if (event.data === '\uD83D\uDC93') {
60
- return;
61
- }
62
- try {
63
- processMessage(JSON.parse(event.data));
64
- }
65
- catch (ex) {
66
- if (studio_shared_1.hotMiddlewareOptions.warn) {
67
- console.warn('Invalid HMR message: ' + event.data + '\n' + ex);
68
- }
69
- }
70
- }
71
- }
72
8
  function createReporter() {
73
9
  const styles = {
74
10
  errors: 'color: #ff0000;',
@@ -153,20 +89,33 @@ function processMessage(obj) {
153
89
  let reporter;
154
90
  const singletonKey = '__webpack_hot_middleware_reporter__';
155
91
  const enableHotMiddleware = () => {
156
- if (typeof window === 'undefined') {
157
- // do nothing
158
- }
159
- else if (typeof window.EventSource === 'undefined') {
160
- console.warn('Unsupported browser: You need a browser that supports EventSource ');
161
- }
162
- else {
163
- connect();
164
- }
165
92
  if (typeof window !== 'undefined') {
166
93
  if (!window[singletonKey]) {
167
94
  window[singletonKey] = createReporter();
168
95
  }
169
96
  reporter = window[singletonKey];
170
97
  }
98
+ window.__remotion_processHmrEvent = (hmrEvent) => {
99
+ processMessage(hmrEvent);
100
+ };
101
+ // Create a standalone SSE listener for HMR events immediately.
102
+ // This is needed because lazy-compiled modules require HMR updates
103
+ // to deliver compiled code, but the React-managed /events SSE
104
+ // (in PreviewServerConnection) only connects after React mounts —
105
+ // which itself depends on lazy modules loading first.
106
+ if (typeof window !== 'undefined' && typeof EventSource !== 'undefined') {
107
+ const source = new EventSource('/events');
108
+ source.addEventListener('message', (event) => {
109
+ try {
110
+ const parsed = JSON.parse(event.data);
111
+ if (parsed.type === 'hmr') {
112
+ processMessage(parsed.hmrEvent);
113
+ }
114
+ }
115
+ catch (_a) {
116
+ // Ignore parse errors
117
+ }
118
+ });
119
+ }
171
120
  };
172
121
  exports.enableHotMiddleware = enableHotMiddleware;
@@ -10,9 +10,7 @@
10
10
  */
11
11
  import type { ModuleMap } from '@remotion/studio-shared';
12
12
  export declare const processUpdate: (hash: string | undefined, moduleMap: ModuleMap, options: {
13
- path: string;
14
13
  timeout: number;
15
14
  reload: boolean;
16
15
  warn: boolean;
17
- heartbeat: number;
18
16
  }) => void;
@@ -7,7 +7,6 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.processUpdate = void 0;
10
- const NotificationCenter_1 = require("../components/Notifications/NotificationCenter");
11
10
  const url_state_1 = require("../helpers/url-state");
12
11
  if (!__webpack_module__.hot) {
13
12
  throw new Error('[Fast refresh] Hot Module Replacement is disabled.');
@@ -50,10 +49,6 @@ function upToDate(hash) {
50
49
  }
51
50
  const processUpdate = function (hash, moduleMap, options) {
52
51
  var _a;
53
- const { reload } = options;
54
- if (!upToDate(hash) && ((_a = __webpack_module__.hot) === null || _a === void 0 ? void 0 : _a.status()) === 'idle') {
55
- check();
56
- }
57
52
  async function check() {
58
53
  var _a;
59
54
  const cb = function (err, updatedModules) {
@@ -137,9 +132,7 @@ const processUpdate = function (hash, moduleMap, options) {
137
132
  }
138
133
  if (options.warn) {
139
134
  console.warn('[Fast refresh] Update check failed: ' + (err.stack || err.message));
140
- if (!window.remotion_unsavedProps) {
141
- (0, url_state_1.reloadUrl)();
142
- }
135
+ (0, url_state_1.reloadUrl)();
143
136
  }
144
137
  }
145
138
  function performReload() {
@@ -148,12 +141,11 @@ const processUpdate = function (hash, moduleMap, options) {
148
141
  }
149
142
  if (options.warn)
150
143
  console.warn('[Fast refresh] Reloading page');
151
- if (window.remotion_unsavedProps) {
152
- (0, NotificationCenter_1.showNotification)('Fast refresh needs to reload the page, but you have unsaved props. Save then reload the page to apply changes.', 1000);
153
- }
154
- else {
155
- (0, url_state_1.reloadUrl)();
156
- }
144
+ (0, url_state_1.reloadUrl)();
145
+ }
146
+ const { reload } = options;
147
+ if (!upToDate(hash) && ((_a = __webpack_module__.hot) === null || _a === void 0 ? void 0 : _a.status()) === 'idle') {
148
+ check();
157
149
  }
158
150
  };
159
151
  exports.processUpdate = processUpdate;
@@ -0,0 +1,3 @@
1
+ import type { SVGProps } from 'react';
2
+ import React from 'react';
3
+ export declare const RedoIcon: React.FC<SVGProps<SVGSVGElement>>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedoIcon = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const RedoIcon = (props) => {
6
+ return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 640 640", ...props, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M552 256L408 256C398.3 256 389.5 250.2 385.8 241.2C382.1 232.2 384.1 221.9 391 215L437.7 168.3C362.4 109.7 253.4 115 184.2 184.2C109.2 259.2 109.2 380.7 184.2 455.7C259.2 530.7 380.7 530.7 455.7 455.7C463.9 447.5 471.2 438.8 477.6 429.6C487.7 415.1 507.7 411.6 522.2 421.7C536.7 431.8 540.2 451.8 530.1 466.3C521.6 478.5 511.9 490.1 501 501C401 601 238.9 601 139 501C39.1 401 39 239 139 139C233.3 44.7 382.7 39.4 483.3 122.8L535 71C541.9 64.1 552.2 62.1 561.2 65.8C570.2 69.5 576 78.3 576 88L576 232C576 245.3 565.3 256 552 256z" }) }));
7
+ };
8
+ exports.RedoIcon = RedoIcon;
@@ -0,0 +1,3 @@
1
+ import type { SVGProps } from 'react';
2
+ import React from 'react';
3
+ export declare const UndoIcon: React.FC<SVGProps<SVGSVGElement>>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UndoIcon = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const UndoIcon = (props) => {
6
+ return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 640 640", ...props, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M88 256L232 256C241.7 256 250.5 250.2 254.2 241.2C257.9 232.2 255.9 221.9 249 215L202.3 168.3C277.6 109.7 386.6 115 455.8 184.2C530.8 259.2 530.8 380.7 455.8 455.7C380.8 530.7 259.3 530.7 184.3 455.7C174.1 445.5 165.3 434.4 157.9 422.7C148.4 407.8 128.6 403.4 113.7 412.9C98.8 422.4 94.4 442.2 103.9 457.1C113.7 472.7 125.4 487.5 139 501C239 601 401 601 501 501C601 401 601 239 501 139C406.8 44.7 257.3 39.3 156.7 122.8L105 71C98.1 64.2 87.8 62.1 78.8 65.8C69.8 69.5 64 78.3 64 88L64 232C64 245.3 74.7 256 88 256z" }) }));
7
+ };
8
+ exports.UndoIcon = UndoIcon;
@@ -171,7 +171,7 @@ const renderToDOM = (content) => {
171
171
  getRootForElement().render(content);
172
172
  };
173
173
  const renderContent = (Root) => {
174
- var _a, _b;
174
+ var _a, _b, _c, _d;
175
175
  const bundleMode = getBundleMode();
176
176
  if (bundleMode.type === 'composition') {
177
177
  const markup = (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { initialCanvasContent: null, onlyRenderComposition: bundleMode.compositionName, currentCompositionMetadata: {
@@ -185,13 +185,13 @@ const renderContent = (Root) => {
185
185
  defaultVideoImageFormat: bundleMode.compositionDefaultVideoImageFormat,
186
186
  defaultPixelFormat: bundleMode.compositionDefaultPixelFormat,
187
187
  defaultProResProfile: bundleMode.compositionDefaultProResProfile,
188
- }, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: window.remotion_logLevel, numberOfAudioTags: 0, audioLatencyHint: (_a = window.remotion_audioLatencyHint) !== null && _a !== void 0 ? _a : 'interactive', visualModeEnabled: false, children: jsx_runtime_1.jsxs(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: [
188
+ }, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', numberOfAudioTags: 0, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'interactive', visualModeEnabled: false, children: jsx_runtime_1.jsxs(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: [
189
189
  jsx_runtime_1.jsx(Root, {}), jsx_runtime_1.jsx(GetVideoComposition, { state: bundleMode })
190
190
  ] }) }) }));
191
191
  renderToDOM(markup);
192
192
  }
193
193
  if (bundleMode.type === 'evaluation') {
194
- const markup = (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { initialCanvasContent: null, onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: window.remotion_logLevel, numberOfAudioTags: 0, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'interactive', visualModeEnabled: false, children: jsx_runtime_1.jsx(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: jsx_runtime_1.jsx(Root, {}) }) }) }));
194
+ const markup = (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { initialCanvasContent: null, onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_c = window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info', numberOfAudioTags: 0, audioLatencyHint: (_d = window.remotion_audioLatencyHint) !== null && _d !== void 0 ? _d : 'interactive', visualModeEnabled: false, children: jsx_runtime_1.jsx(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: jsx_runtime_1.jsx(Root, {}) }) }) }));
195
195
  renderToDOM(markup);
196
196
  }
197
197
  if (bundleMode.type === 'index') {
@@ -227,6 +227,7 @@ const setBundleModeAndUpdate = (state) => {
227
227
  exports.setBundleModeAndUpdate = setBundleModeAndUpdate;
228
228
  if (typeof window !== 'undefined') {
229
229
  const getUnevaluatedComps = () => {
230
+ var _a, _b, _c;
230
231
  if (!remotion_1.Internals.getRoot()) {
231
232
  throw new Error('registerRoot() was never called. 1. Make sure you specified the correct entrypoint for your bundle. 2. If your registerRoot() call is deferred, use the delayRender/continueRender pattern to tell Remotion to wait.');
232
233
  }
@@ -236,14 +237,14 @@ if (typeof window !== 'undefined') {
236
237
  const compositions = remotion_1.Internals.compositionsRef.current.getCompositions();
237
238
  const canSerializeDefaultProps = getCanSerializeDefaultProps(compositions);
238
239
  if (!canSerializeDefaultProps) {
239
- remotion_1.Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, 'defaultProps are too big to serialize - trying to find the problematic composition...');
240
- remotion_1.Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, 'Serialization:', compositions);
240
+ remotion_1.Internals.Log.warn({ logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', tag: null }, 'defaultProps are too big to serialize - trying to find the problematic composition...');
241
+ remotion_1.Internals.Log.warn({ logLevel: (_b = window.remotion_logLevel) !== null && _b !== void 0 ? _b : 'info', tag: null }, 'Serialization:', compositions);
241
242
  for (const comp of compositions) {
242
243
  if (!getCanSerializeDefaultProps(comp)) {
243
244
  throw new Error(`defaultProps too big - could not serialize - the defaultProps of composition with ID ${comp.id} - the object that was passed to defaultProps was too big. Learn how to mitigate this error by visiting https://remotion.dev/docs/troubleshooting/serialize-defaultprops`);
244
245
  }
245
246
  }
246
- remotion_1.Internals.Log.warn({ logLevel: window.remotion_logLevel, tag: null }, 'Could not single out a problematic composition - The composition list as a whole is too big to serialize.');
247
+ remotion_1.Internals.Log.warn({ logLevel: (_c = window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info', tag: null }, 'Could not single out a problematic composition - The composition list as a whole is too big to serialize.');
247
248
  throw new Error('defaultProps too big - Could not serialize - an object that was passed to defaultProps was too big. Learn how to mitigate this error by visiting https://remotion.dev/docs/troubleshooting/serialize-defaultprops');
248
249
  }
249
250
  return compositions;
@@ -7,6 +7,7 @@ const remotion_1 = require("remotion");
7
7
  const get_zod_schema_from_primitive_1 = require("../api/get-zod-schema-from-primitive");
8
8
  const get_zod_if_possible_1 = require("../components/get-zod-if-possible");
9
9
  const get_current_edited_value_1 = require("./get-current-edited-value");
10
+ const visual_control_store_1 = require("./visual-control-store");
10
11
  exports.VisualControlsTabActivatedContext = (0, react_1.createContext)(false);
11
12
  exports.VisualControlsContext = (0, react_1.createContext)({
12
13
  handles: {},
@@ -32,16 +33,18 @@ const VisualControlsProvider = ({ children }) => {
32
33
  };
33
34
  }, [handles]);
34
35
  const setControl = (0, react_1.useCallback)((key, value) => {
35
- var _a, _b, _c, _d;
36
- const currentUnsaved = (_b = (_a = imperativeHandles.current) === null || _a === void 0 ? void 0 : _a[key]) === null || _b === void 0 ? void 0 : _b.unsavedValue;
37
- const currentSavedState = (_d = (_c = imperativeHandles.current) === null || _c === void 0 ? void 0 : _c[key]) === null || _d === void 0 ? void 0 : _d.valueInCode;
36
+ var _a;
37
+ const existingHandle = (_a = imperativeHandles.current) === null || _a === void 0 ? void 0 : _a[key];
38
+ const currentSavedState = existingHandle === null || existingHandle === void 0 ? void 0 : existingHandle.valueInCode;
38
39
  const changedSavedValue = value.valueInCode !== currentSavedState;
39
- const changedUnsavedValue = currentUnsaved === undefined && value.valueInCode !== undefined;
40
+ const changedUnsavedValue = existingHandle === undefined && value.valueInCode !== undefined;
40
41
  imperativeHandles.current = {
41
42
  ...imperativeHandles.current,
42
43
  [key]: {
43
44
  ...value,
44
- unsavedValue: currentUnsaved !== null && currentUnsaved !== void 0 ? currentUnsaved : value.valueInCode,
45
+ unsavedValue: existingHandle !== undefined && !changedSavedValue
46
+ ? existingHandle.unsavedValue
47
+ : value.valueInCode,
45
48
  valueInCode: value.valueInCode,
46
49
  },
47
50
  };
@@ -93,6 +96,7 @@ const VisualControlsProvider = ({ children }) => {
93
96
  },
94
97
  };
95
98
  updateHandles();
99
+ visual_control_store_1.visualControlStore.emitChange();
96
100
  }, [updateHandles]);
97
101
  (0, react_1.useImperativeHandle)(exports.visualControlRef, () => {
98
102
  return {
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVisualControlEditedValue = void 0;
4
4
  const getVisualControlEditedValue = ({ handles, key, }) => {
5
- var _a;
6
- var _b;
7
- // TODO: What if z.null()
8
- return (_b = (_a = handles === null || handles === void 0 ? void 0 : handles[key]) === null || _a === void 0 ? void 0 : _a.unsavedValue) !== null && _b !== void 0 ? _b : null;
5
+ const handle = handles === null || handles === void 0 ? void 0 : handles[key];
6
+ if (handle === undefined) {
7
+ return null;
8
+ }
9
+ return handle.unsavedValue;
9
10
  };
10
11
  exports.getVisualControlEditedValue = getVisualControlEditedValue;
@@ -0,0 +1,7 @@
1
+ type Listener = () => void;
2
+ export declare const visualControlStore: {
3
+ subscribe(listener: Listener): () => void;
4
+ getSnapshot(): number;
5
+ emitChange(): void;
6
+ };
7
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.visualControlStore = void 0;
4
+ let version = 0;
5
+ const listeners = new Set();
6
+ exports.visualControlStore = {
7
+ subscribe(listener) {
8
+ listeners.add(listener);
9
+ return () => {
10
+ listeners.delete(listener);
11
+ };
12
+ },
13
+ getSnapshot() {
14
+ return version;
15
+ },
16
+ emitChange() {
17
+ version++;
18
+ for (const listener of listeners) {
19
+ listener();
20
+ }
21
+ },
22
+ };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio"
4
4
  },
5
5
  "name": "@remotion/studio",
6
- "version": "4.0.438",
6
+ "version": "4.0.440",
7
7
  "description": "APIs for interacting with the Remotion Studio",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -26,13 +26,13 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "7.5.3",
29
- "remotion": "4.0.438",
30
- "@remotion/player": "4.0.438",
31
- "@remotion/media-utils": "4.0.438",
32
- "@remotion/renderer": "4.0.438",
33
- "@remotion/web-renderer": "4.0.438",
34
- "@remotion/studio-shared": "4.0.438",
35
- "@remotion/zod-types": "4.0.438",
29
+ "remotion": "4.0.440",
30
+ "@remotion/player": "4.0.440",
31
+ "@remotion/media-utils": "4.0.440",
32
+ "@remotion/renderer": "4.0.440",
33
+ "@remotion/web-renderer": "4.0.440",
34
+ "@remotion/studio-shared": "4.0.440",
35
+ "@remotion/zod-types": "4.0.440",
36
36
  "mediabunny": "1.39.2",
37
37
  "memfs": "3.4.3",
38
38
  "source-map": "0.7.3",
@@ -43,7 +43,7 @@
43
43
  "react": "19.2.3",
44
44
  "react-dom": "19.2.3",
45
45
  "@types/semver": "^7.3.4",
46
- "@remotion/eslint-config-internal": "4.0.438",
46
+ "@remotion/eslint-config-internal": "4.0.440",
47
47
  "eslint": "9.19.0",
48
48
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
49
49
  },
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
- export declare const GlobalPropsEditorUpdateButton: React.FC<{
3
- readonly compositionId: string;
4
- readonly currentDefaultProps: Record<string, unknown>;
5
- }>;