remotion 4.0.533 → 4.0.535

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 (107) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/AbsoluteFill.d.ts +1 -6
  3. package/dist/cjs/AbsoluteFill.js +1 -1
  4. package/dist/cjs/Composition.js +15 -20
  5. package/dist/cjs/CompositionManager.d.ts +4 -4
  6. package/dist/cjs/CompositionManagerContext.d.ts +1 -6
  7. package/dist/cjs/CompositionManagerContext.js +0 -4
  8. package/dist/cjs/CompositionManagerProvider.js +77 -172
  9. package/dist/cjs/CompositionRegistryProvider.d.ts +5 -0
  10. package/dist/cjs/CompositionRegistryProvider.js +142 -0
  11. package/dist/cjs/DefaultPremountContext.d.ts +1 -0
  12. package/dist/cjs/DefaultPremountContext.js +6 -0
  13. package/dist/cjs/Folder.js +11 -20
  14. package/dist/cjs/HtmlInCanvas.d.ts +2 -2
  15. package/dist/cjs/HtmlInCanvas.js +179 -31
  16. package/dist/cjs/IFrame.js +40 -8
  17. package/dist/cjs/Img.js +2 -1
  18. package/dist/cjs/Interactive.d.ts +12 -0
  19. package/dist/cjs/Interactive.js +19 -8
  20. package/dist/cjs/RemotionRoot.js +2 -1
  21. package/dist/cjs/Sequence.d.ts +6 -2
  22. package/dist/cjs/Sequence.js +107 -40
  23. package/dist/cjs/SequenceActivityBoundary.d.ts +10 -0
  24. package/dist/cjs/SequenceActivityBoundary.js +88 -0
  25. package/dist/cjs/SequenceActivityBudget.d.ts +13 -0
  26. package/dist/cjs/SequenceActivityBudget.js +181 -0
  27. package/dist/cjs/SequenceManager.d.ts +13 -29
  28. package/dist/cjs/SequenceManager.js +36 -176
  29. package/dist/cjs/SequenceRegistryProvider.d.ts +4 -0
  30. package/dist/cjs/SequenceRegistryProvider.js +292 -0
  31. package/dist/cjs/Track.d.ts +13 -0
  32. package/dist/cjs/Track.js +33 -0
  33. package/dist/cjs/animated-image/AnimatedImage.js +42 -30
  34. package/dist/cjs/audio/AudioForPreview.js +54 -41
  35. package/dist/cjs/audio/get-audio-sync-anchor-tolerance.d.ts +1 -0
  36. package/dist/cjs/audio/get-audio-sync-anchor-tolerance.js +11 -0
  37. package/dist/cjs/audio/use-audio-context.js +26 -7
  38. package/dist/cjs/canvas-image/CanvasImage.js +4 -2
  39. package/dist/cjs/committed-metadata.d.ts +68 -0
  40. package/dist/cjs/committed-metadata.js +39 -0
  41. package/dist/cjs/component-identity.d.ts +6 -0
  42. package/dist/cjs/component-identity.js +39 -0
  43. package/dist/cjs/composition-registry-fallback.d.ts +14 -0
  44. package/dist/cjs/composition-registry-fallback.js +35 -0
  45. package/dist/cjs/create-element-source-proxy.d.ts +4 -0
  46. package/dist/cjs/create-element-source-proxy.js +46 -0
  47. package/dist/cjs/default-premount-in-seconds.d.ts +3 -0
  48. package/dist/cjs/default-premount-in-seconds.js +12 -0
  49. package/dist/cjs/effects/Solid.js +5 -3
  50. package/dist/cjs/effects/canvas-pool.d.ts +1 -0
  51. package/dist/cjs/effects/canvas-pool.js +15 -10
  52. package/dist/cjs/effects/run-effect-chain.js +3 -3
  53. package/dist/cjs/effects/use-memoized-effects.d.ts +3 -1
  54. package/dist/cjs/effects/use-memoized-effects.js +104 -21
  55. package/dist/cjs/enable-sequence-stack-traces.d.ts +2 -8
  56. package/dist/cjs/enable-sequence-stack-traces.js +7 -38
  57. package/dist/cjs/evaluate-source-expressions.d.ts +5 -0
  58. package/dist/cjs/evaluate-source-expressions.js +98 -0
  59. package/dist/cjs/freeze.js +9 -8
  60. package/dist/cjs/index.d.ts +2 -2
  61. package/dist/cjs/index.js +3 -3
  62. package/dist/cjs/interactivity-schema.d.ts +45 -9
  63. package/dist/cjs/interactivity-schema.js +30 -3
  64. package/dist/cjs/internals.d.ts +113 -27
  65. package/dist/cjs/internals.js +37 -7
  66. package/dist/cjs/interpolate-keyframed-status.d.ts +4 -0
  67. package/dist/cjs/interpolate-keyframed-status.js +38 -1
  68. package/dist/cjs/interpolate.d.ts +12 -0
  69. package/dist/cjs/interpolate.js +7 -0
  70. package/dist/cjs/no-react.d.ts +6 -0
  71. package/dist/cjs/no-react.js +9 -0
  72. package/dist/cjs/optimistic-sequence-deletion.d.ts +17 -0
  73. package/dist/cjs/optimistic-sequence-deletion.js +114 -0
  74. package/dist/cjs/registry-store.d.ts +17 -0
  75. package/dist/cjs/registry-store.js +68 -0
  76. package/dist/cjs/sequence-activity-context.d.ts +13 -0
  77. package/dist/cjs/sequence-activity-context.js +20 -0
  78. package/dist/cjs/sequence-activity-defaults.d.ts +1 -0
  79. package/dist/cjs/sequence-activity-defaults.js +4 -0
  80. package/dist/cjs/sequence-outline.js +1 -2
  81. package/dist/cjs/sequence-registry-context.d.ts +26 -0
  82. package/dist/cjs/sequence-registry-context.js +71 -0
  83. package/dist/cjs/series/index.d.ts +2 -1
  84. package/dist/cjs/series/index.js +15 -5
  85. package/dist/cjs/timeline-position-state.js +11 -3
  86. package/dist/cjs/timeline-track-context.d.ts +10 -0
  87. package/dist/cjs/timeline-track-context.js +6 -0
  88. package/dist/cjs/use-lazy-component.js +29 -15
  89. package/dist/cjs/use-media-in-timeline.d.ts +7 -14
  90. package/dist/cjs/use-media-in-timeline.js +29 -119
  91. package/dist/cjs/use-premounting.js +3 -4
  92. package/dist/cjs/use-schema.d.ts +32 -18
  93. package/dist/cjs/use-sequence-registration.d.ts +1 -1
  94. package/dist/cjs/use-sequence-registration.js +22 -6
  95. package/dist/cjs/use-video.d.ts +7 -2
  96. package/dist/cjs/use-video.js +11 -3
  97. package/dist/cjs/version.d.ts +1 -1
  98. package/dist/cjs/version.js +1 -1
  99. package/dist/cjs/video/VideoForPreview.js +55 -42
  100. package/dist/cjs/video/html5-video.js +1 -1
  101. package/dist/cjs/with-interactivity-schema.js +48 -16
  102. package/dist/cjs/wrap-remotion-context.d.ts +17 -2
  103. package/dist/cjs/wrap-remotion-context.js +108 -4
  104. package/dist/esm/index.mjs +3526 -2259
  105. package/dist/esm/no-react.mjs +149 -35
  106. package/dist/esm/version.mjs +1 -1
  107. package/package.json +2 -2
@@ -37,11 +37,12 @@ exports.AudioForPreview = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = require("react");
39
39
  const react_2 = __importStar(require("react"));
40
+ const committed_metadata_js_1 = require("../committed-metadata.js");
40
41
  const get_cross_origin_value_js_1 = require("../get-cross-origin-value.js");
41
42
  const log_level_context_js_1 = require("../log-level-context.js");
42
43
  const prefetch_js_1 = require("../prefetch.js");
43
44
  const random_js_1 = require("../random.js");
44
- const sequence_order_marker_js_1 = require("../sequence-order-marker.js");
45
+ const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
45
46
  const SequenceContext_js_1 = require("../SequenceContext.js");
46
47
  const use_amplification_js_1 = require("../use-amplification.js");
47
48
  const use_media_in_timeline_js_1 = require("../use-media-in-timeline.js");
@@ -55,38 +56,24 @@ const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
55
56
  const use_audio_frame_js_1 = require("./use-audio-frame.js");
56
57
  const use_media_audio_state_js_1 = require("./use-media-audio-state.js");
57
58
  const AudioForDevelopmentForwardRefFunction = (props, ref) => {
58
- var _a, _b, _c;
59
+ var _a;
59
60
  const [initialShouldPreMountAudioElements] = (0, react_2.useState)(props.shouldPreMountAudioTags);
60
61
  if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
61
62
  throw new Error('Cannot change the behavior for pre-mounting audio tags dynamically.');
62
63
  }
63
64
  const logLevel = (0, log_level_context_js_1.useLogLevel)();
64
- const { volume, muted, playbackRate, preservePitch, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, toneFrequency, useWebAudioApi, onError, onNativeError, audioStreamIndex, ...nativeProps } = props;
65
+ const { timelineId, userPreferredVolume, isMutedForPlayback, volume, muted, playbackRate, preservePitch, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, crossOrigin, delayRenderRetries, delayRenderTimeoutInMilliseconds, toneFrequency, useWebAudioApi, onError, onNativeError, audioStreamIndex, ...nativeProps } = props;
65
66
  // Typecheck that we are not accidentially passing unrecognized props
66
67
  // to the DOM
67
68
  const _propsValid = true;
68
69
  if (!_propsValid) {
69
70
  throw new Error('typecheck error');
70
71
  }
71
- const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
72
- const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
73
72
  if (!src) {
74
73
  throw new TypeError("No 'src' was passed to <Html5Audio>.");
75
74
  }
76
75
  const preloadedSrc = (0, prefetch_js_1.usePreload)(src);
77
76
  const sequenceContext = (0, react_2.useContext)(SequenceContext_js_1.SequenceContext);
78
- const { isStudio } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
79
- const [timelineId] = (0, react_2.useState)(() => String(Math.random()));
80
- const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
81
- frame: volumePropFrame,
82
- volume,
83
- mediaVolume,
84
- });
85
- const { isMutedForTimeline, isMutedForPlayback } = (0, use_media_audio_state_js_1.useMediaAudioState)({
86
- muted: muted !== null && muted !== void 0 ? muted : false,
87
- volume: userPreferredVolume,
88
- audioEnabled: true,
89
- });
90
77
  (0, volume_safeguard_js_1.warnAboutTooHighVolume)(userPreferredVolume);
91
78
  const crossOriginValue = (0, get_cross_origin_value_js_1.getCrossOriginValue)({
92
79
  crossOrigin,
@@ -124,26 +111,6 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
124
111
  premounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
125
112
  postmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
126
113
  });
127
- const getStack = (0, react_1.useCallback)(() => {
128
- return _remotionInternalStack !== null && _remotionInternalStack !== void 0 ? _remotionInternalStack : null;
129
- }, [_remotionInternalStack]);
130
- (0, use_media_in_timeline_js_1.useMediaInTimeline)({
131
- volume,
132
- mediaVolume,
133
- src,
134
- mediaType: 'audio',
135
- playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
136
- displayName: name !== null && name !== void 0 ? name : null,
137
- id: timelineId,
138
- getStack,
139
- showInTimeline,
140
- premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
141
- postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
142
- loopDisplay: undefined,
143
- loopVolumeCurveBehavior: loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat',
144
- documentationLink: 'https://www.remotion.dev/docs/html5-audio',
145
- muted: isMutedForTimeline,
146
- });
147
114
  // putting playback before useVolume
148
115
  // because volume looks at playbackrate
149
116
  (0, use_media_playback_js_1.useMediaPlayback)({
@@ -181,7 +148,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
181
148
  *
182
149
  * Need to import it from React to fix React 17 ESM support.
183
150
  */
184
- const effectToUse = (_c = react_2.default.useInsertionEffect) !== null && _c !== void 0 ? _c : react_2.default.useLayoutEffect;
151
+ const effectToUse = (_a = react_2.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_2.default.useLayoutEffect;
185
152
  // Disconnecting the SharedElementSourceNodes if the Audio tag unmounts to prevent leak.
186
153
  // https://github.com/remotion-dev/remotion/issues/6285
187
154
  // But useInsertionEffect will fire before other effects, meaning the
@@ -218,9 +185,55 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
218
185
  };
219
186
  }, [audioRef, src]);
220
187
  if (initialShouldPreMountAudioElements) {
221
- return isStudio ? (jsx_runtime_1.jsx(sequence_order_marker_js_1.SequenceOrderMarker, { sequenceId: timelineId, outlineChildrenRef: null, children: null })) : null;
188
+ return null;
222
189
  }
223
190
  const audio = (jsx_runtime_1.jsx("audio", { ref: audioRef, preload: "metadata", crossOrigin: crossOriginValue, ...propsToPass }));
224
- return isStudio ? (jsx_runtime_1.jsx(sequence_order_marker_js_1.SequenceOrderMarker, { sequenceId: timelineId, outlineChildrenRef: null, children: audio })) : (audio);
191
+ return audio;
192
+ };
193
+ const AudioForPreviewContent = (0, react_2.forwardRef)(AudioForDevelopmentForwardRefFunction);
194
+ const AudioForPreviewRefForwardingFunction = (props, ref) => {
195
+ var _a, _b;
196
+ const { volume, muted, playbackRate, src, name, _remotionInternalStack, showInTimeline, loopVolumeCurveBehavior, } = props;
197
+ const [timelineId] = (0, react_2.useState)(() => String(Math.random()));
198
+ const sequenceContext = (0, react_2.useContext)(SequenceContext_js_1.SequenceContext);
199
+ const { isStudio } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
200
+ const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
201
+ const volumePropFrame = (0, use_audio_frame_js_1.useFrameForVolumeProp)(loopVolumeCurveBehavior !== null && loopVolumeCurveBehavior !== void 0 ? loopVolumeCurveBehavior : 'repeat');
202
+ const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
203
+ frame: volumePropFrame,
204
+ volume,
205
+ mediaVolume,
206
+ });
207
+ const { isMutedForTimeline, isMutedForPlayback } = (0, use_media_audio_state_js_1.useMediaAudioState)({
208
+ muted: muted !== null && muted !== void 0 ? muted : false,
209
+ volume: userPreferredVolume,
210
+ audioEnabled: true,
211
+ });
212
+ const getStack = (0, react_1.useCallback)(() => {
213
+ return _remotionInternalStack !== null && _remotionInternalStack !== void 0 ? _remotionInternalStack : null;
214
+ }, [_remotionInternalStack]);
215
+ const { registration } = (0, use_media_in_timeline_js_1.useMediaInTimelineRegistration)({
216
+ src,
217
+ mediaType: 'audio',
218
+ playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
219
+ displayName: name !== null && name !== void 0 ? name : null,
220
+ id: timelineId,
221
+ getStack,
222
+ showInTimeline,
223
+ premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
224
+ postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
225
+ loopDisplay: undefined,
226
+ documentationLink: 'https://www.remotion.dev/docs/html5-audio',
227
+ muted: isMutedForTimeline,
228
+ });
229
+ const metadata = (0, react_2.useMemo)(() => isStudio || registration !== null
230
+ ? {
231
+ type: 'sequence',
232
+ id: timelineId,
233
+ value: registration,
234
+ outlineChildrenRef: null,
235
+ }
236
+ : null, [isStudio, registration, timelineId]);
237
+ return (jsx_runtime_1.jsx(committed_metadata_js_1.CommittedMetadataProvider, { value: null, _remotionCommitMetadata: metadata, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(AudioForPreviewContent, { ...props, ref: ref, timelineId: timelineId, userPreferredVolume: userPreferredVolume, isMutedForPlayback: isMutedForPlayback }) }) }));
225
238
  };
226
- exports.AudioForPreview = (0, react_2.forwardRef)(AudioForDevelopmentForwardRefFunction);
239
+ exports.AudioForPreview = (0, react_2.forwardRef)(AudioForPreviewRefForwardingFunction);
@@ -0,0 +1 @@
1
+ export declare const getAudioSyncAnchorTolerance: (audioContext: AudioContext) => number;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAudioSyncAnchorTolerance = void 0;
4
+ const ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
5
+ // The tolerance is measured in AudioContext seconds.
6
+ const getAudioSyncAnchorTolerance = (audioContext) => {
7
+ const { baseLatency, outputLatency } = audioContext;
8
+ const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
9
+ return ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + baseLatency + safeOutputLatency;
10
+ };
11
+ exports.getAudioSyncAnchorTolerance = getAudioSyncAnchorTolerance;
@@ -46,6 +46,8 @@ const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, sampleR
46
46
  // Tracks the state we are transitioning towards while resume()/suspend()
47
47
  // have been called but the native state has not updated yet.
48
48
  let transitionTarget = null;
49
+ let transitionId = 0;
50
+ let pendingResume = null;
49
51
  const getState = () => {
50
52
  const nativeState = audioContext.state;
51
53
  if (transitionTarget === 'running' && nativeState !== 'running') {
@@ -57,24 +59,41 @@ const useSingletonAudioContext = ({ logLevel, latencyHint, audioEnabled, sampleR
57
59
  return nativeState;
58
60
  };
59
61
  const resume = () => {
62
+ const id = ++transitionId;
60
63
  transitionTarget = 'running';
64
+ // Keep resume synchronous so it retains the browser's user activation.
61
65
  const promise = audioContext.resume();
62
- promise.finally(() => {
63
- if (transitionTarget === 'running') {
66
+ pendingResume = promise;
67
+ return promise.finally(() => {
68
+ if (pendingResume === promise) {
69
+ pendingResume = null;
70
+ }
71
+ if (transitionId === id) {
64
72
  transitionTarget = null;
65
73
  }
66
74
  });
67
- return promise;
68
75
  };
69
76
  const suspend = () => {
77
+ const id = ++transitionId;
70
78
  transitionTarget = 'suspended';
71
- const promise = audioContext.suspend();
72
- promise.finally(() => {
73
- if (transitionTarget === 'suspended') {
79
+ // Chromium can freeze the audio clock if suspend runs before an
80
+ // in-flight resume settles, while its reported state is still suspended.
81
+ // A newer playback request must cancel this deferred suspension.
82
+ const promise = pendingResume
83
+ ? pendingResume
84
+ .catch(() => { })
85
+ .then(() => {
86
+ if (transitionId !== id) {
87
+ return;
88
+ }
89
+ return audioContext.suspend();
90
+ })
91
+ : audioContext.suspend();
92
+ return promise.finally(() => {
93
+ if (transitionId === id) {
74
94
  transitionTarget = null;
75
95
  }
76
96
  });
77
- return promise;
78
97
  };
79
98
  return {
80
99
  audioContext,
@@ -12,6 +12,7 @@ const freeze_js_1 = require("../freeze.js");
12
12
  const interactivity_schema_js_1 = require("../interactivity-schema.js");
13
13
  const prefetch_js_1 = require("../prefetch.js");
14
14
  const resolve_sequence_duration_js_1 = require("../resolve-sequence-duration.js");
15
+ const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
15
16
  const Sequence_js_1 = require("../Sequence.js");
16
17
  const SequenceContext_js_1 = require("../SequenceContext.js");
17
18
  const truncate_src_for_label_js_1 = require("../truncate-src-for-label.js");
@@ -111,7 +112,7 @@ const waitForNextFrame = ({ onFrame, }) => {
111
112
  return () => cancelAnimationFrame(frame);
112
113
  };
113
114
  const CanvasImageContent = (0, react_1.forwardRef)(({ src, crossOrigin, width, height, fit = 'fill', effects, controls, onError, className, style, id, pauseWhenLoading, maxRetries = 2, delayRenderRetries, delayRenderTimeoutInMilliseconds, ...canvasProps }, ref) => {
114
- var _a;
115
+ var _a, _b;
115
116
  const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
116
117
  const { delayPlayback } = (0, use_buffer_state_js_1.useBufferState)();
117
118
  const [outputCanvas, setOutputCanvas] = (0, react_1.useState)(null);
@@ -121,6 +122,7 @@ const CanvasImageContent = (0, react_1.forwardRef)(({ src, crossOrigin, width, h
121
122
  const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
122
123
  effects,
123
124
  overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null,
125
+ videoConfigValues: (_b = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _b !== void 0 ? _b : null,
124
126
  });
125
127
  const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
126
128
  const pendingLoadDelayRef = (0, react_1.useRef)(null);
@@ -363,7 +365,7 @@ const CanvasImageInner = (0, react_1.forwardRef)(({ src, crossOrigin, width, hei
363
365
  style: premountingStyle,
364
366
  componentName: _remotionInternalCropComponentName !== null && _remotionInternalCropComponentName !== void 0 ? _remotionInternalCropComponentName : '<CanvasImage />',
365
367
  });
366
- return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, loop: loop, durationInFrames: durationInFrames, freeze: freeze, hidden: hidden, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, name: name !== null && name !== void 0 ? name : '<CanvasImage>', _remotionInternalDocumentationLink: _remotionInternalDocumentationLink !== null && _remotionInternalDocumentationLink !== void 0 ? _remotionInternalDocumentationLink : 'https://www.remotion.dev/docs/canvasimage', controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(CanvasImageContent, { ref: actualRef, src: src, crossOrigin: crossOrigin, width: width, height: height, fit: fit, effects: effects, controls: controls, className: className, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, id: id, onError: onError, pauseWhenLoading: pauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, ...canvasProps }) }) }));
368
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, loop: loop, durationInFrames: durationInFrames, freeze: freeze, hidden: hidden, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, name: name !== null && name !== void 0 ? name : '<CanvasImage>', _remotionInternalDocumentationLink: _remotionInternalDocumentationLink !== null && _remotionInternalDocumentationLink !== void 0 ? _remotionInternalDocumentationLink : 'https://www.remotion.dev/docs/canvasimage', controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(CanvasImageContent, { ref: actualRef, src: src, crossOrigin: crossOrigin, width: width, height: height, fit: fit, effects: effects, controls: controls, className: className, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, id: id, onError: onError, pauseWhenLoading: pauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, ...canvasProps }) }) }) }));
367
369
  });
368
370
  /*
369
371
  * @description Renders a static image to a `<canvas>` and applies Remotion effects.
@@ -0,0 +1,68 @@
1
+ import type { Provider, ProviderExoticComponent, ProviderProps, RefObject } from 'react';
2
+ import type { AnyComposition, TSequence } from './CompositionManager.js';
3
+ import type { TFolder } from './Folder.js';
4
+ export declare const COMMIT_ORDER_EVENT = "remotion:commit-order";
5
+ export declare const COMMIT_REGISTRATION_ERROR_EVENT = "remotion:commit-registration-error";
6
+ export declare const isCommitRegistrationObserverInstalled: () => boolean;
7
+ export type CompositionAndFolderOrderItem = {
8
+ readonly type: 'composition';
9
+ readonly id: string;
10
+ } | {
11
+ readonly type: 'folder';
12
+ readonly id: string;
13
+ };
14
+ export declare const getCompositionAndFolderOrderKey: (item: CompositionAndFolderOrderItem) => string;
15
+ export type CommitOrderEventDetail = {
16
+ readonly sequenceManagers: readonly {
17
+ readonly managerId: string;
18
+ readonly sequenceIds: readonly string[];
19
+ }[];
20
+ };
21
+ export declare const getFolderOrderId: ({ name, parent, }: {
22
+ readonly name: string;
23
+ readonly parent: string | null;
24
+ }) => string;
25
+ export type CommittedSequenceSnapshot = {
26
+ readonly sequences: readonly TSequence[];
27
+ readonly sequenceIds: readonly string[];
28
+ };
29
+ export type CommittedCompositionSnapshot = {
30
+ readonly compositions: readonly AnyComposition[];
31
+ readonly folders: readonly TFolder[];
32
+ readonly orderIds: readonly string[];
33
+ };
34
+ export type CommittedMetadata = {
35
+ readonly type: 'sequence';
36
+ readonly id: string;
37
+ readonly value: TSequence | null;
38
+ readonly outlineChildrenRef: RefObject<Element | null> | null;
39
+ } | {
40
+ readonly type: 'composition';
41
+ readonly id: string;
42
+ readonly value: AnyComposition;
43
+ } | {
44
+ readonly type: 'folder';
45
+ readonly id: string;
46
+ readonly value: TFolder;
47
+ } | {
48
+ readonly type: 'sequence-manager';
49
+ readonly id: string;
50
+ readonly onCommit: ((sequences: readonly TSequence[], sequenceIds: readonly string[]) => void) | null;
51
+ } | {
52
+ readonly type: 'composition-manager';
53
+ readonly id: string;
54
+ readonly onCommit: ((snapshot: CommittedCompositionSnapshot) => void) | null;
55
+ };
56
+ export declare const withCommittedMetadata: <T>(provider: Provider<T>) => ProviderExoticComponent<ProviderProps<T> & {
57
+ readonly _remotionCommitMetadata: CommittedMetadata | null;
58
+ }>;
59
+ export declare const CommittedMetadataProvider: ProviderExoticComponent<ProviderProps<null> & {
60
+ readonly _remotionCommitMetadata: CommittedMetadata | null;
61
+ }>;
62
+ export declare const CommittedMetadataInternals: {
63
+ metadataProp: "_remotionCommitMetadata";
64
+ eventName: string;
65
+ installationMarker: symbol;
66
+ failureMarker: symbol;
67
+ registrationErrorEventName: string;
68
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommittedMetadataInternals = exports.CommittedMetadataProvider = exports.withCommittedMetadata = exports.getFolderOrderId = exports.getCompositionAndFolderOrderKey = exports.isCommitRegistrationObserverInstalled = exports.COMMIT_REGISTRATION_ERROR_EVENT = exports.COMMIT_ORDER_EVENT = void 0;
4
+ const react_1 = require("react");
5
+ const COMMITTED_METADATA_PROP = '_remotionCommitMetadata';
6
+ exports.COMMIT_ORDER_EVENT = 'remotion:commit-order';
7
+ exports.COMMIT_REGISTRATION_ERROR_EVENT = 'remotion:commit-registration-error';
8
+ const COMMIT_OBSERVER_INSTALLATION_MARKER = Symbol.for('remotion.commit-order-observer-installed');
9
+ const COMMIT_OBSERVER_FAILURE_MARKER = Symbol.for('remotion.commit-registration-observer-failed');
10
+ const isCommitRegistrationObserverInstalled = () => {
11
+ if (typeof window === 'undefined') {
12
+ return false;
13
+ }
14
+ const hook = Reflect.get(window, '__REACT_DEVTOOLS_GLOBAL_HOOK__');
15
+ return (typeof hook === 'object' &&
16
+ hook !== null &&
17
+ Reflect.get(hook, 'isDisabled') !== true &&
18
+ Reflect.get(hook, COMMIT_OBSERVER_INSTALLATION_MARKER) === true &&
19
+ Reflect.get(hook, COMMIT_OBSERVER_FAILURE_MARKER) !== true);
20
+ };
21
+ exports.isCommitRegistrationObserverInstalled = isCommitRegistrationObserverInstalled;
22
+ const getCompositionAndFolderOrderKey = (item) => `${item.type}:${item.id}`;
23
+ exports.getCompositionAndFolderOrderKey = getCompositionAndFolderOrderKey;
24
+ const getFolderOrderId = ({ name, parent, }) => [parent, name].filter(Boolean).join('/');
25
+ exports.getFolderOrderId = getFolderOrderId;
26
+ // This is the same provider, with an additional private prop type. Metadata
27
+ // stays outside its context value, so edits do not notify context consumers.
28
+ const withCommittedMetadata = (provider) => provider;
29
+ exports.withCommittedMetadata = withCommittedMetadata;
30
+ // Leaves without an existing provider still need a committed Fiber when their
31
+ // content is null. Its constant context value never carries registry metadata.
32
+ exports.CommittedMetadataProvider = (0, exports.withCommittedMetadata)((0, react_1.createContext)(null).Provider);
33
+ exports.CommittedMetadataInternals = {
34
+ metadataProp: COMMITTED_METADATA_PROP,
35
+ eventName: exports.COMMIT_ORDER_EVENT,
36
+ installationMarker: COMMIT_OBSERVER_INSTALLATION_MARKER,
37
+ failureMarker: COMMIT_OBSERVER_FAILURE_MARKER,
38
+ registrationErrorEventName: exports.COMMIT_REGISTRATION_ERROR_EVENT,
39
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type ComponentIdentityResolver = (component: unknown) => unknown;
3
+ export declare const setComponentIdentityResolver: (resolver: ComponentIdentityResolver | null) => void;
4
+ export declare const resolveComponentIdentity: (component: unknown) => unknown;
5
+ export declare const getSingleChildComponent: (children: React.ReactNode) => unknown;
6
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getSingleChildComponent = exports.resolveComponentIdentity = exports.setComponentIdentityResolver = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const is_inside_series_js_1 = require("./series/is-inside-series.js");
9
+ // Studio installs a resolver that maps refreshed component implementations to
10
+ // the stable family object maintained by React Refresh.
11
+ let componentIdentityResolver = null;
12
+ const setComponentIdentityResolver = (resolver) => {
13
+ componentIdentityResolver = resolver;
14
+ };
15
+ exports.setComponentIdentityResolver = setComponentIdentityResolver;
16
+ const resolveComponentIdentity = (component) => {
17
+ var _a;
18
+ return (_a = componentIdentityResolver === null || componentIdentityResolver === void 0 ? void 0 : componentIdentityResolver(component)) !== null && _a !== void 0 ? _a : component;
19
+ };
20
+ exports.resolveComponentIdentity = resolveComponentIdentity;
21
+ const getSingleChildComponent = (children) => {
22
+ const mountedChildren = react_1.default.Children.toArray(children);
23
+ if (mountedChildren.length !== 1) {
24
+ return null;
25
+ }
26
+ const child = mountedChildren[0];
27
+ if (!react_1.default.isValidElement(child)) {
28
+ return null;
29
+ }
30
+ // Series inserts this transparent context boundary around its authored children.
31
+ if (child.type === is_inside_series_js_1.IsNotInsideSeriesProvider) {
32
+ return (0, exports.getSingleChildComponent)(child.props.children);
33
+ }
34
+ if (typeof child.type !== 'function' && typeof child.type !== 'object') {
35
+ return null;
36
+ }
37
+ return (0, exports.resolveComponentIdentity)(child.type);
38
+ };
39
+ exports.getSingleChildComponent = getSingleChildComponent;
@@ -0,0 +1,14 @@
1
+ import type { AnyComposition } from './CompositionManager.js';
2
+ import type { TFolder } from './Folder.js';
3
+ export type CommittedCompositionEntry = {
4
+ readonly type: 'composition';
5
+ readonly value: AnyComposition;
6
+ } | {
7
+ readonly type: 'folder';
8
+ readonly value: TFolder;
9
+ };
10
+ export declare const CompositionRegistryFallbackContext: import("react").Context<{
11
+ readonly entries: Map<object, CommittedCompositionEntry>;
12
+ readonly notifyCommit: () => void;
13
+ } | null>;
14
+ export declare const useCommittedCompositionEntry: (entry: CommittedCompositionEntry | null) => void;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCommittedCompositionEntry = exports.CompositionRegistryFallbackContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.CompositionRegistryFallbackContext = (0, react_1.createContext)(null);
6
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? react_1.useEffect : react_1.useLayoutEffect;
7
+ // The fallback stages descriptors during layout effects and publishes one
8
+ // complete snapshot after the commit, including mount and unmount changes.
9
+ const useCommittedCompositionEntry = (entry) => {
10
+ const registry = (0, react_1.useContext)(exports.CompositionRegistryFallbackContext);
11
+ const key = (0, react_1.useRef)({});
12
+ useIsomorphicLayoutEffect(() => {
13
+ if (registry === null) {
14
+ return;
15
+ }
16
+ if (entry === null) {
17
+ registry.entries.delete(key.current);
18
+ }
19
+ else {
20
+ registry.entries.set(key.current, entry);
21
+ }
22
+ registry.notifyCommit();
23
+ }, [entry, registry]);
24
+ useIsomorphicLayoutEffect(() => {
25
+ if (registry === null) {
26
+ return;
27
+ }
28
+ const identity = key.current;
29
+ return () => {
30
+ registry.entries.delete(identity);
31
+ registry.notifyCommit();
32
+ };
33
+ }, [registry]);
34
+ };
35
+ exports.useCommittedCompositionEntry = useCommittedCompositionEntry;
@@ -0,0 +1,4 @@
1
+ import type React from 'react';
2
+ import type JsxRuntimeDev from 'react/jsx-dev-runtime';
3
+ import type JsxRuntime from 'react/jsx-runtime';
4
+ export declare const createElementSourceProxy: <T extends typeof React.createElement | typeof JsxRuntime.jsx | typeof JsxRuntimeDev.jsxDEV>(api: T, sourceArgumentIndex: number | null, getSourceFileName: (fileName: string) => string) => T;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createElementSourceProxy = void 0;
4
+ const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
5
+ const componentsToAddStacksTo = (0, enable_sequence_stack_traces_js_1.getComponentsToAddStacksTo)();
6
+ const internalStackProp = enable_sequence_stack_traces_js_1.REMOTION_INTERNAL_STACK_PROP;
7
+ const createElementSourceProxy = (api, sourceArgumentIndex, getSourceFileName) => {
8
+ return new Proxy(api, {
9
+ apply(target, thisArg, argArray) {
10
+ const component = argArray[0];
11
+ if (componentsToAddStacksTo.includes(component)) {
12
+ const [first, props, ...rest] = argArray;
13
+ const source = sourceArgumentIndex === null ? null : argArray[sourceArgumentIndex];
14
+ const existingStack = props === null || props === void 0 ? void 0 : props[internalStackProp];
15
+ // Internal wrappers already captured the authored location in their controls.
16
+ const controlsStack = !existingStack &&
17
+ component === (0, enable_sequence_stack_traces_js_1.getSequenceComponent)() &&
18
+ (props === null || props === void 0 ? void 0 : props.controls)
19
+ ? (0, enable_sequence_stack_traces_js_1.getStackForControls)(props.controls)
20
+ : null;
21
+ const stack = existingStack ||
22
+ (controlsStack !== null && controlsStack !== void 0 ? controlsStack : (source &&
23
+ typeof source.fileName === 'string' &&
24
+ typeof source.lineNumber === 'number' &&
25
+ typeof source.columnNumber === 'number'
26
+ ? (0, enable_sequence_stack_traces_js_1.makeOriginalSourceStack)({
27
+ fileName: getSourceFileName(source.fileName),
28
+ lineNumber: source.lineNumber,
29
+ // JSX development locations are one-based, like stack traces.
30
+ // Resolved source locations and AST lookups use zero-based columns.
31
+ columnNumber: source.columnNumber - 1,
32
+ })
33
+ : new Error().stack));
34
+ const newProps = existingStack
35
+ ? { ...props }
36
+ : {
37
+ ...(props !== null && props !== void 0 ? props : {}),
38
+ [internalStackProp]: stack,
39
+ };
40
+ return Reflect.apply(target, thisArg, [first, newProps, ...rest]);
41
+ }
42
+ return Reflect.apply(target, thisArg, argArray);
43
+ },
44
+ });
45
+ };
46
+ exports.createElementSourceProxy = createElementSourceProxy;
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_PREMOUNT_IN_SECONDS: number;
2
+ export declare const DEFAULT_STUDIO_PREMOUNT_IN_SECONDS = 2;
3
+ export declare const validateDefaultPremountInSeconds: (value: unknown) => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateDefaultPremountInSeconds = exports.DEFAULT_STUDIO_PREMOUNT_IN_SECONDS = exports.DEFAULT_PREMOUNT_IN_SECONDS = void 0;
4
+ const v5_flag_js_1 = require("./v5-flag.js");
5
+ exports.DEFAULT_PREMOUNT_IN_SECONDS = v5_flag_js_1.ENABLE_V5_BREAKING_CHANGES ? 2 : 0;
6
+ exports.DEFAULT_STUDIO_PREMOUNT_IN_SECONDS = 2;
7
+ const validateDefaultPremountInSeconds = (value) => {
8
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
9
+ throw new TypeError(`defaultPremountInSeconds must be a finite, non-negative number, but got ${String(value)}.`);
10
+ }
11
+ };
12
+ exports.validateDefaultPremountInSeconds = validateDefaultPremountInSeconds;
@@ -7,6 +7,7 @@ const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-trac
7
7
  const freeze_js_1 = require("../freeze.js");
8
8
  const interactivity_schema_js_1 = require("../interactivity-schema.js");
9
9
  const resolve_sequence_duration_js_1 = require("../resolve-sequence-duration.js");
10
+ const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
10
11
  const Sequence_js_1 = require("../Sequence.js");
11
12
  const use_crop_style_js_1 = require("../use-crop-style.js");
12
13
  const use_delay_render_js_1 = require("../use-delay-render.js");
@@ -65,7 +66,7 @@ exports.solidSchema = {
65
66
  ...interactivity_schema_js_1.borderRadiusSchema,
66
67
  ...interactivity_schema_js_1.cropSchema,
67
68
  };
68
- const SolidInner = ({ color, width, height, effects = [], className, style, pixelDensity, overrideId, reference, }) => {
69
+ const SolidInner = ({ color, width, height, effects = [], className, style, pixelDensity, overrideId, videoConfigValues, reference, }) => {
69
70
  const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
70
71
  const resolvedPixelDensity = resolveSolidPixelDensity(pixelDensity);
71
72
  const canvasWidth = Math.ceil(width * resolvedPixelDensity);
@@ -74,6 +75,7 @@ const SolidInner = ({ color, width, height, effects = [], className, style, pixe
74
75
  const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
75
76
  effects,
76
77
  overrideId: overrideId !== null && overrideId !== void 0 ? overrideId : null,
78
+ videoConfigValues,
77
79
  });
78
80
  const sourceCanvas = (0, react_1.useMemo)(() => {
79
81
  if (typeof document === 'undefined') {
@@ -157,7 +159,7 @@ const SolidInner = ({ color, width, height, effects = [], className, style, pixe
157
159
  return (jsx_runtime_1.jsx("canvas", { ref: canvasRef, width: canvasWidth, height: canvasHeight, className: className, style: canvasStyle }));
158
160
  };
159
161
  const SolidOuter = (0, react_1.forwardRef)(({ effects = [], controls, color, height, width, className, durationInFrames, style, name, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, loop, freeze, hidden, showInTimeline, pixelDensity, cropLeft, cropRight, cropTop, cropBottom, ...props }, ref) => {
160
- var _a;
162
+ var _a, _b;
161
163
  props;
162
164
  const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
163
165
  const actualRef = (0, react_1.useRef)(null);
@@ -186,7 +188,7 @@ const SolidOuter = (0, react_1.forwardRef)(({ effects = [], controls, color, hei
186
188
  style: premountingStyle,
187
189
  componentName: '<Solid />',
188
190
  });
189
- return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, hidden: hidden, showInTimeline: showInTimeline, controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<Solid>', _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/solid", ...props, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(SolidInner, { reference: actualRef, overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null, color: color, height: height, width: width, className: className, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, effects: effects, pixelDensity: pixelDensity }) }) }));
191
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, hidden: hidden, showInTimeline: showInTimeline, controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<Solid>', _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/solid", ...props, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(SolidInner, { reference: actualRef, videoConfigValues: (_a = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _a !== void 0 ? _a : null, overrideId: (_b = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _b !== void 0 ? _b : null, color: color, height: height, width: width, className: className, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, effects: effects, pixelDensity: pixelDensity }) }) }) }));
190
192
  });
191
193
  exports.Solid = (0, with_interactivity_schema_js_1.withInteractivitySchema)({
192
194
  Component: SolidOuter,
@@ -9,6 +9,7 @@ export declare class CanvasPool {
9
9
  private readonly onContextLost;
10
10
  private disposed;
11
11
  constructor(width: number, height: number, onContextLost: (canvas: HTMLCanvasElement) => void);
12
+ getCanvas(backend: Backend, index: 0 | 1): HTMLCanvasElement;
12
13
  getPair(backend: Backend): CanvasPair;
13
14
  assertContextNotLost(canvas: HTMLCanvasElement): void;
14
15
  dispose(): void;
@@ -30,20 +30,25 @@ class CanvasPool {
30
30
  this.height = height;
31
31
  this.onContextLost = onContextLost;
32
32
  }
33
- getPair(backend) {
33
+ getCanvas(backend, index) {
34
+ var _a;
34
35
  if (this.disposed) {
35
36
  throw new Error('Effect chain state was used after it had been cleaned up');
36
37
  }
37
- const existing = this.pairs.get(backend);
38
- if (existing) {
39
- return existing;
38
+ let pair = this.pairs.get(backend);
39
+ if (!pair) {
40
+ pair = [null, null];
41
+ this.pairs.set(backend, pair);
40
42
  }
41
- const pair = [
42
- this.allocateCanvas(backend),
43
- this.allocateCanvas(backend),
44
- ];
45
- this.pairs.set(backend, pair);
46
- return pair;
43
+ // A single effect needs one target. Allocate its ping-pong partner only
44
+ // when a later pass actually uses it.
45
+ (_a = pair[index]) !== null && _a !== void 0 ? _a : (pair[index] = this.allocateCanvas(backend));
46
+ return pair[index];
47
+ }
48
+ getPair(backend) {
49
+ this.getCanvas(backend, 0);
50
+ this.getCanvas(backend, 1);
51
+ return this.pairs.get(backend);
47
52
  }
48
53
  assertContextNotLost(canvas) {
49
54
  if (this.lostContexts.has(canvas)) {