remotion 4.0.534 → 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 (101) 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 +0 -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 -169
  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 +177 -30
  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 +2 -3
  22. package/dist/cjs/Sequence.js +72 -38
  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 +4 -22
  28. package/dist/cjs/SequenceManager.js +36 -196
  29. package/dist/cjs/SequenceRegistryProvider.d.ts +4 -0
  30. package/dist/cjs/SequenceRegistryProvider.js +292 -0
  31. package/dist/cjs/Track.d.ts +10 -3
  32. package/dist/cjs/Track.js +7 -6
  33. package/dist/cjs/animated-image/AnimatedImage.js +42 -31
  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 +2 -1
  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 +2 -1
  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.js +96 -17
  54. package/dist/cjs/enable-sequence-stack-traces.d.ts +2 -8
  55. package/dist/cjs/enable-sequence-stack-traces.js +7 -38
  56. package/dist/cjs/freeze.js +4 -1
  57. package/dist/cjs/index.d.ts +0 -2
  58. package/dist/cjs/index.js +0 -2
  59. package/dist/cjs/interactivity-schema.d.ts +45 -9
  60. package/dist/cjs/interactivity-schema.js +30 -3
  61. package/dist/cjs/internals.d.ts +104 -25
  62. package/dist/cjs/internals.js +29 -7
  63. package/dist/cjs/interpolate-keyframed-status.d.ts +4 -0
  64. package/dist/cjs/interpolate-keyframed-status.js +38 -1
  65. package/dist/cjs/interpolate.d.ts +12 -0
  66. package/dist/cjs/interpolate.js +7 -0
  67. package/dist/cjs/no-react.d.ts +4 -0
  68. package/dist/cjs/no-react.js +6 -0
  69. package/dist/cjs/optimistic-sequence-deletion.d.ts +17 -0
  70. package/dist/cjs/optimistic-sequence-deletion.js +114 -0
  71. package/dist/cjs/registry-store.d.ts +17 -0
  72. package/dist/cjs/registry-store.js +68 -0
  73. package/dist/cjs/sequence-activity-context.d.ts +13 -0
  74. package/dist/cjs/sequence-activity-context.js +20 -0
  75. package/dist/cjs/sequence-activity-defaults.d.ts +1 -0
  76. package/dist/cjs/sequence-activity-defaults.js +4 -0
  77. package/dist/cjs/sequence-outline.js +1 -2
  78. package/dist/cjs/sequence-registry-context.d.ts +26 -0
  79. package/dist/cjs/sequence-registry-context.js +71 -0
  80. package/dist/cjs/series/index.d.ts +2 -1
  81. package/dist/cjs/series/index.js +12 -4
  82. package/dist/cjs/timeline-position-state.js +11 -3
  83. package/dist/cjs/timeline-track-context.d.ts +1 -0
  84. package/dist/cjs/use-lazy-component.js +29 -15
  85. package/dist/cjs/use-media-in-timeline.d.ts +7 -14
  86. package/dist/cjs/use-media-in-timeline.js +15 -117
  87. package/dist/cjs/use-premounting.js +3 -4
  88. package/dist/cjs/use-sequence-registration.d.ts +1 -1
  89. package/dist/cjs/use-sequence-registration.js +22 -6
  90. package/dist/cjs/use-video.d.ts +7 -2
  91. package/dist/cjs/use-video.js +11 -3
  92. package/dist/cjs/version.d.ts +1 -1
  93. package/dist/cjs/version.js +1 -1
  94. package/dist/cjs/video/VideoForPreview.js +55 -42
  95. package/dist/cjs/with-interactivity-schema.js +40 -14
  96. package/dist/cjs/wrap-remotion-context.d.ts +15 -2
  97. package/dist/cjs/wrap-remotion-context.js +101 -4
  98. package/dist/esm/index.mjs +3352 -2284
  99. package/dist/esm/no-react.mjs +71 -35
  100. package/dist/esm/version.mjs +1 -1
  101. package/package.json +2 -2
package/dist/cjs/Track.js CHANGED
@@ -8,22 +8,23 @@ const interactivity_schema_js_1 = require("./interactivity-schema.js");
8
8
  const Sequence_js_1 = require("./Sequence.js");
9
9
  const timeline_track_context_js_1 = require("./timeline-track-context.js");
10
10
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
11
+ // A packed row has no container bar to drag. Expose its linear timing in the
12
+ // inspector, but keep looping and freezing as programmatic operations.
13
+ const { freeze: _freeze, layout: _layout, ...trackSequenceSchema } = interactivity_schema_js_1.sequenceSchema;
11
14
  const trackSchema = {
12
- name: interactivity_schema_js_1.sequenceSchema.name,
13
- hidden: interactivity_schema_js_1.sequenceSchema.hidden,
15
+ ...trackSequenceSchema,
16
+ ...interactivity_schema_js_1.sequenceTimingSchema,
14
17
  };
15
- // Series variants share the Track foundation while retaining their own
16
- // Sequence props, layout defaults, and interactivity schemas.
17
18
  const TrackWithoutSchema = ({ name = 'Track', children, layout = 'none', ...props }) => {
18
19
  const [id] = (0, react_1.useState)(() => String(Math.random()));
19
20
  const tracksEnabled = (0, react_1.useContext)(timeline_track_context_js_1.ExperimentalTracksEnabledContext);
20
21
  const value = (0, react_1.useMemo)(() => (tracksEnabled ? { id, name } : null), [id, name, tracksEnabled]);
21
- return (jsx_runtime_1.jsx(timeline_track_context_js_1.TimelineTrackContext.Provider, { value: value, children: jsx_runtime_1.jsx(Sequence_js_1.SequenceWithoutSchema, { ...props, name: name, layout: layout, _remotionInternalTimelineTrack: { role: 'track' }, children: children }) }));
22
+ return (jsx_runtime_1.jsx(timeline_track_context_js_1.TimelineTrackContext.Provider, { value: value, children: jsx_runtime_1.jsx(Sequence_js_1.SequenceWithoutSchema, { _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/track", ...props, name: name, layout: layout, _remotionInternalTimelineTrack: { role: 'track', seriesOffset: null }, children: children }) }));
22
23
  };
23
24
  exports.TrackWithoutSchema = TrackWithoutSchema;
24
25
  /** Groups clips on one Studio timeline row and applies Sequence timing. */
25
26
  exports.Track = (0, with_interactivity_schema_js_1.withInteractivitySchema)({
26
- Component: exports.TrackWithoutSchema,
27
+ Component: (props) => jsx_runtime_1.jsx(exports.TrackWithoutSchema, { ...props, layout: "none" }),
27
28
  componentName: '<Track>',
28
29
  componentIdentity: 'dev.remotion.remotion.Track',
29
30
  schema: trackSchema,
@@ -4,12 +4,12 @@ exports.AnimatedImage = exports.animatedImageSchema = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_2 = require("react");
7
- const cancel_render_js_1 = require("../cancel-render.js");
8
7
  const use_memoized_effects_js_1 = require("../effects/use-memoized-effects.js");
9
8
  const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js");
10
9
  const freeze_js_1 = require("../freeze.js");
11
10
  const interactivity_schema_js_1 = require("../interactivity-schema.js");
12
11
  const resolve_sequence_duration_js_1 = require("../resolve-sequence-duration.js");
12
+ const sequence_activity_context_js_1 = require("../sequence-activity-context.js");
13
13
  const Sequence_js_1 = require("../Sequence.js");
14
14
  const use_crop_style_js_1 = require("../use-crop-style.js");
15
15
  const use_current_frame_js_1 = require("../use-current-frame.js");
@@ -52,11 +52,11 @@ const getCanvasPropsFromSequenceProps = (props) => {
52
52
  return canvasProps;
53
53
  };
54
54
  const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', requestInit, effects, controls, ...props }, canvasRef) => {
55
- var _a, _b;
55
+ var _a, _b, _c;
56
56
  const resolvedSrc = (0, resolve_image_source_1.resolveAnimatedImageSource)(src);
57
- const [imageDecoder, setImageDecoder] = (0, react_2.useState)(null);
58
- const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
59
- const [decodeHandle] = (0, react_2.useState)(() => delayRender(`Rendering <AnimatedImage/> with src="${resolvedSrc}"`));
57
+ const [decodedImage, setDecodedImage] = (0, react_2.useState)(null);
58
+ const imageDecoder = (_a = decodedImage === null || decodedImage === void 0 ? void 0 : decodedImage.decoder) !== null && _a !== void 0 ? _a : null;
59
+ const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
60
60
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
61
61
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
62
62
  const currentTime = (0, get_current_time_js_1.getCurrentTime)({ frame, playbackRate, fps });
@@ -68,8 +68,8 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
68
68
  const ref = (0, react_2.useRef)(null);
69
69
  const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
70
70
  effects,
71
- overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null,
72
- videoConfigValues: (_b = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _b !== void 0 ? _b : null,
71
+ overrideId: (_b = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _b !== void 0 ? _b : null,
72
+ videoConfigValues: (_c = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _c !== void 0 ? _c : null,
73
73
  });
74
74
  (0, react_2.useImperativeHandle)(canvasRef, () => {
75
75
  var _a;
@@ -80,7 +80,8 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
80
80
  return c;
81
81
  }, []);
82
82
  const [initialLoopBehavior] = (0, react_2.useState)(() => loopBehavior);
83
- (0, react_2.useEffect)(() => {
83
+ (0, react_2.useLayoutEffect)(() => {
84
+ const decodeHandle = delayRender(`Rendering <AnimatedImage/> with src="${resolvedSrc}"`);
84
85
  const controller = new AbortController();
85
86
  let cancelled = false;
86
87
  let continued = false;
@@ -103,8 +104,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
103
104
  d.close();
104
105
  return;
105
106
  }
106
- setImageDecoder(d);
107
- continueRenderOnce();
107
+ setDecodedImage({ decoder: d, handle: decodeHandle });
108
108
  })
109
109
  .catch((err) => {
110
110
  if (cancelled) {
@@ -119,7 +119,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
119
119
  continueRenderOnce();
120
120
  }
121
121
  else {
122
- (0, cancel_render_js_1.cancelRender)(err);
122
+ cancelRender(err);
123
123
  }
124
124
  });
125
125
  return () => {
@@ -129,11 +129,12 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
129
129
  };
130
130
  }, [
131
131
  resolvedSrc,
132
- decodeHandle,
133
132
  onError,
134
133
  requestInitKey,
135
134
  initialLoopBehavior,
136
135
  continueRender,
136
+ delayRender,
137
+ cancelRender,
137
138
  ]);
138
139
  (0, react_2.useEffect)(() => {
139
140
  return () => {
@@ -141,10 +142,12 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
141
142
  };
142
143
  }, [imageDecoder]);
143
144
  (0, react_2.useLayoutEffect)(() => {
144
- if (!imageDecoder) {
145
+ if (!imageDecoder || !decodedImage) {
145
146
  return;
146
147
  }
147
148
  const delay = delayRender(`Rendering frame at ${currentTime} of <AnimatedImage src="${src}"/>`);
149
+ // The frame hold takes over only after the decoded image has committed.
150
+ continueRender(decodedImage.handle);
148
151
  let cancelled = false;
149
152
  imageDecoder
150
153
  .getFrame(currentTime, loopBehavior)
@@ -172,7 +175,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
172
175
  continueRender(delay);
173
176
  }
174
177
  else {
175
- (0, cancel_render_js_1.cancelRender)(err);
178
+ cancelRender(err);
176
179
  }
177
180
  });
178
181
  return () => {
@@ -182,6 +185,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
182
185
  }, [
183
186
  currentTime,
184
187
  imageDecoder,
188
+ decodedImage,
185
189
  loopBehavior,
186
190
  onError,
187
191
  src,
@@ -191,6 +195,7 @@ const AnimatedImageContent = (0, react_2.forwardRef)(({ src, width, height, onEr
191
195
  fit,
192
196
  width,
193
197
  height,
198
+ cancelRender,
194
199
  ]);
195
200
  return (jsx_runtime_1.jsx(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, effects: memoizedEffects, ...props }));
196
201
  });
@@ -237,20 +242,20 @@ const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, lo
237
242
  requestInit,
238
243
  ...canvasProps,
239
244
  };
240
- 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, playbackRate: playbackRate, durationInFrames: durationInFrames, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...sequenceProps, children: jsx_runtime_1.jsx(AnimatedImageContent, { ...animatedImageProps, ref: actualRef, effects: effects, controls: controls }) }) }));
245
+ 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, playbackRate: playbackRate, durationInFrames: durationInFrames, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...sequenceProps, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(AnimatedImageContent, { ...animatedImageProps, ref: actualRef, effects: effects, controls: controls }) }) }) }));
241
246
  };
242
247
  const AnimatedImageWithIntrinsicDuration = (props) => {
243
248
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
244
- const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)();
249
+ const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
245
250
  const { src, requestInit, trimBefore } = props;
246
251
  const requestInitRef = (0, react_2.useRef)(requestInit);
247
252
  requestInitRef.current = requestInit;
248
253
  const onErrorRef = (0, react_2.useRef)(props.onError);
249
254
  onErrorRef.current = props.onError;
250
- const [handle] = (0, react_2.useState)(() => delayRender(`Finding duration of <AnimatedImage src="${src}" />`));
251
- const [durationInFrames, setDurationInFrames] = (0, react_2.useState)(null);
252
- const [failed, setFailed] = (0, react_2.useState)(false);
253
- (0, react_2.useEffect)(() => {
255
+ const [duration, setDuration] = (0, react_2.useState)(null);
256
+ const [failedHandle, setFailedHandle] = (0, react_2.useState)(null);
257
+ (0, react_2.useLayoutEffect)(() => {
258
+ const handle = delayRender(`Finding duration of <AnimatedImage src="${src}" />`);
254
259
  const controller = new AbortController();
255
260
  let cancelled = false;
256
261
  (0, get_duration_in_seconds_js_1.getAnimatedImageDurationInSeconds)({
@@ -259,9 +264,12 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
259
264
  requestInit: requestInitRef.current,
260
265
  contentType: null,
261
266
  })
262
- .then((duration) => {
267
+ .then((durationInSeconds) => {
263
268
  if (!cancelled) {
264
- setDurationInFrames(Math.ceil(duration * fps) - (trimBefore !== null && trimBefore !== void 0 ? trimBefore : 0));
269
+ setDuration({
270
+ durationInFrames: Math.ceil(durationInSeconds * fps) - (trimBefore !== null && trimBefore !== void 0 ? trimBefore : 0),
271
+ handle,
272
+ });
265
273
  }
266
274
  })
267
275
  .catch((error) => {
@@ -270,10 +278,10 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
270
278
  }
271
279
  if (onErrorRef.current) {
272
280
  onErrorRef.current(error);
273
- setFailed(true);
281
+ setFailedHandle(handle);
274
282
  }
275
283
  else {
276
- (0, cancel_render_js_1.cancelRender)(error);
284
+ cancelRender(error);
277
285
  }
278
286
  });
279
287
  return () => {
@@ -281,16 +289,19 @@ const AnimatedImageWithIntrinsicDuration = (props) => {
281
289
  controller.abort();
282
290
  continueRender(handle);
283
291
  };
284
- }, [continueRender, fps, handle, src, trimBefore]);
285
- (0, react_2.useEffect)(() => {
286
- if (durationInFrames !== null || failed) {
287
- continueRender(handle);
292
+ }, [cancelRender, continueRender, delayRender, fps, src, trimBefore]);
293
+ (0, react_2.useLayoutEffect)(() => {
294
+ if (duration !== null) {
295
+ continueRender(duration.handle);
296
+ }
297
+ if (failedHandle !== null) {
298
+ continueRender(failedHandle);
288
299
  }
289
- }, [continueRender, durationInFrames, failed, handle]);
290
- if (durationInFrames === null || failed) {
300
+ }, [continueRender, duration, failedHandle]);
301
+ if (duration === null || failedHandle !== null) {
291
302
  return null;
292
303
  }
293
- return jsx_runtime_1.jsx(AnimatedImageInner, { ...props, durationInFrames: durationInFrames });
304
+ return (jsx_runtime_1.jsx(AnimatedImageInner, { ...props, durationInFrames: duration.durationInFrames }));
294
305
  };
295
306
  const AnimatedImageComponent = (props) => {
296
307
  var _a;
@@ -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");
@@ -364,7 +365,7 @@ const CanvasImageInner = (0, react_1.forwardRef)(({ src, crossOrigin, width, hei
364
365
  style: premountingStyle,
365
366
  componentName: _remotionInternalCropComponentName !== null && _remotionInternalCropComponentName !== void 0 ? _remotionInternalCropComponentName : '<CanvasImage />',
366
367
  });
367
- 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 }) }) }) }));
368
369
  });
369
370
  /*
370
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;