remotion 4.0.532 → 4.0.534

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 (40) hide show
  1. package/dist/cjs/CompositionManager.d.ts +10 -0
  2. package/dist/cjs/CompositionManagerProvider.js +6 -9
  3. package/dist/cjs/HtmlInCanvas.d.ts +2 -0
  4. package/dist/cjs/HtmlInCanvas.js +17 -4
  5. package/dist/cjs/Sequence.d.ts +5 -0
  6. package/dist/cjs/Sequence.js +73 -11
  7. package/dist/cjs/SequenceManager.d.ts +37 -7
  8. package/dist/cjs/SequenceManager.js +317 -30
  9. package/dist/cjs/Track.d.ts +6 -0
  10. package/dist/cjs/Track.js +32 -0
  11. package/dist/cjs/animated-image/AnimatedImage.js +2 -1
  12. package/dist/cjs/canvas-image/CanvasImage.js +2 -1
  13. package/dist/cjs/effects/Solid.js +4 -3
  14. package/dist/cjs/effects/use-memoized-effects.d.ts +3 -1
  15. package/dist/cjs/effects/use-memoized-effects.js +12 -6
  16. package/dist/cjs/evaluate-source-expressions.d.ts +5 -0
  17. package/dist/cjs/evaluate-source-expressions.js +98 -0
  18. package/dist/cjs/freeze.js +6 -8
  19. package/dist/cjs/index.d.ts +2 -0
  20. package/dist/cjs/index.js +3 -1
  21. package/dist/cjs/internals.d.ts +13 -3
  22. package/dist/cjs/internals.js +11 -0
  23. package/dist/cjs/no-react.d.ts +2 -0
  24. package/dist/cjs/no-react.js +3 -0
  25. package/dist/cjs/series/index.js +3 -1
  26. package/dist/cjs/timeline-track-context.d.ts +9 -0
  27. package/dist/cjs/timeline-track-context.js +6 -0
  28. package/dist/cjs/use-media-in-timeline.js +14 -2
  29. package/dist/cjs/use-schema.d.ts +32 -18
  30. package/dist/cjs/use-sequence-registration.js +1 -1
  31. package/dist/cjs/version.d.ts +1 -1
  32. package/dist/cjs/version.js +1 -1
  33. package/dist/cjs/video/html5-video.js +1 -1
  34. package/dist/cjs/with-interactivity-schema.js +13 -7
  35. package/dist/cjs/wrap-remotion-context.d.ts +2 -0
  36. package/dist/cjs/wrap-remotion-context.js +8 -1
  37. package/dist/esm/index.mjs +788 -315
  38. package/dist/esm/no-react.mjs +78 -0
  39. package/dist/esm/version.mjs +1 -1
  40. package/package.json +2 -2
@@ -7,6 +7,7 @@ import type { EffectDefinition } from './effects/effect-types.js';
7
7
  import type { InteractivitySchema } from './interactivity-schema.js';
8
8
  import type { InferProps, PropsIfHasProps } from './props-if-has-props.js';
9
9
  import type { RuntimeValueSnapshot, RuntimeValueStore } from './runtime-value-store.js';
10
+ import type { TimelineTrackItem } from './timeline-track-context.js';
10
11
  import type { VideoConfigValues } from './video-config.js';
11
12
  export type TComposition<Schema extends AnyZodObject, Props extends Record<string, unknown>> = {
12
13
  width: number | undefined;
@@ -77,14 +78,23 @@ export type TSequence = {
77
78
  from: number;
78
79
  trimBefore: number | null;
79
80
  duration: number;
81
+ /** Infer the timeline display duration from children without changing playback. */
82
+ readonly autoDuration?: boolean | null;
83
+ /** Whether the wrapper can restore its duration from its scenes. */
84
+ readonly canInferDuration?: boolean | null;
85
+ /** Full scene duration in the parent clock, before container clipping. */
86
+ readonly unclippedDuration?: number | null;
80
87
  id: string;
81
88
  displayName: string;
82
89
  documentationLink: string | null;
83
90
  parent: string | null;
84
91
  showInTimeline: boolean;
85
92
  timelineOrder: number | null;
93
+ timelineTrack?: TimelineTrackItem;
86
94
  loopDisplay: LoopDisplay | undefined;
87
95
  getStack: () => string | null;
96
+ /** Read the committed child clock without updating timeline metadata each frame. */
97
+ getCurrentFrame?: (() => number) | null;
88
98
  premountDisplay: number | null;
89
99
  postmountDisplay: number | null;
90
100
  controls: SequenceRegistrationControls | null;
@@ -28,11 +28,10 @@ const CompositionManagerProvider = ({ children, onlyRenderComposition, currentCo
28
28
  // CompositionManagerProvider state
29
29
  const currentcompositionsRef = (0, react_1.useRef)(compositions);
30
30
  const updateCompositions = (0, react_1.useCallback)((updateComps) => {
31
- setCompositions((comps) => {
32
- const updated = updateComps(comps);
33
- currentcompositionsRef.current = updated;
34
- return updated;
35
- });
31
+ // The renderer may read registrations before React commits the state.
32
+ const updated = updateComps(currentcompositionsRef.current);
33
+ currentcompositionsRef.current = updated;
34
+ setCompositions(updated);
36
35
  }, []);
37
36
  const registerComposition = (0, react_1.useCallback)((comp) => {
38
37
  const orderKey = (0, sequence_order_marker_js_1.getCompositionAndFolderOrderKey)({
@@ -58,10 +57,8 @@ const CompositionManagerProvider = ({ children, onlyRenderComposition, currentCo
58
57
  }, [updateCompositions]);
59
58
  const unregisterComposition = (0, react_1.useCallback)((id) => {
60
59
  internalOrderRef.current.delete((0, sequence_order_marker_js_1.getCompositionAndFolderOrderKey)({ type: 'composition', id }));
61
- setCompositions((comps) => {
62
- return comps.filter((c) => c.id !== id);
63
- });
64
- }, []);
60
+ updateCompositions((comps) => comps.filter((c) => c.id !== id));
61
+ }, [updateCompositions]);
65
62
  const registerFolder = (0, react_1.useCallback)((name, parent, stack) => {
66
63
  const orderKey = (0, sequence_order_marker_js_1.getCompositionAndFolderOrderKey)({
67
64
  type: 'folder',
@@ -72,6 +72,7 @@ export type HtmlInCanvasOnPaintParams = {
72
72
  readonly pixelDensity: number;
73
73
  };
74
74
  export declare const isHtmlInCanvasSupported: () => boolean;
75
+ export declare const isHtmlInCanvasNestingSupported: () => boolean;
75
76
  /** Generic fallback for consumers that cannot inspect the current browser. */
76
77
  export declare const HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = "HTML in Canvas requires Chrome 149 or newer with Canvas Draw Element enabled at chrome://flags/#canvas-draw-element.";
77
78
  export declare const getHtmlInCanvasUnsupportedMessage: () => string;
@@ -319,4 +320,5 @@ export declare const HtmlInCanvas: React.ForwardRefExoticComponent<Omit<Interact
319
320
  readonly _remotionInternalCanvasSiblings?: React.ReactNode;
320
321
  } & React.RefAttributes<HTMLCanvasElement>> & {
321
322
  readonly isSupported: () => boolean;
323
+ readonly isNestingSupported: () => boolean;
322
324
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HtmlInCanvas = exports.htmlInCanvasSchema = exports.getHtmlInCanvasUnsupportedMessage = exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = exports.isHtmlInCanvasSupported = void 0;
3
+ exports.HtmlInCanvas = exports.htmlInCanvasSchema = exports.getHtmlInCanvasUnsupportedMessage = exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = exports.isHtmlInCanvasNestingSupported = exports.isHtmlInCanvasSupported = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const run_effect_chain_js_1 = require("./effects/run-effect-chain.js");
@@ -54,6 +54,17 @@ const isHtmlInCanvasSupported = () => {
54
54
  return cachedSupport;
55
55
  };
56
56
  exports.isHtmlInCanvasSupported = isHtmlInCanvasSupported;
57
+ const MINIMUM_CHROME_VERSION_FOR_NESTED_HTML_IN_CANVAS = 157;
58
+ const isHtmlInCanvasNestingSupported = () => {
59
+ var _a;
60
+ if (!(0, exports.isHtmlInCanvasSupported)() || typeof navigator === 'undefined') {
61
+ return false;
62
+ }
63
+ const chromeVersion = (_a = navigator.userAgent.match(/(?:Chrome|Chromium)\/(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
64
+ return (chromeVersion !== undefined &&
65
+ Number(chromeVersion) >= MINIMUM_CHROME_VERSION_FOR_NESTED_HTML_IN_CANVAS);
66
+ };
67
+ exports.isHtmlInCanvasNestingSupported = isHtmlInCanvasNestingSupported;
57
68
  /** Generic fallback for consumers that cannot inspect the current browser. */
58
69
  exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = 'HTML in Canvas requires Chrome 149 or newer with Canvas Draw Element enabled at chrome://flags/#canvas-draw-element.';
59
70
  const getHtmlInCanvasUnsupportedMessage = () => {
@@ -136,11 +147,11 @@ const defaultOnPaint = ({ canvas, elementImage, }) => {
136
147
  /* eslint-enable react/require-default-props */
137
148
  const HtmlInCanvasAncestorContext = (0, react_1.createContext)(false);
138
149
  const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, children, canvasSiblings, onPaint, onInit, pixelDensity, controls, style, }, ref) => {
139
- var _a;
150
+ var _a, _b;
140
151
  const isInsideAncestorHtmlInCanvas = (0, react_1.useContext)(HtmlInCanvasAncestorContext);
141
152
  assertHtmlInCanvasDimensions(width, height);
142
- if (isInsideAncestorHtmlInCanvas) {
143
- throw new Error('<HtmlInCanvas> components cannot be nested. Chrome does not reliably render nested HTML-in-canvas subtrees. Consider merging the effects into one <HtmlInCanvas> if you can.');
153
+ if (isInsideAncestorHtmlInCanvas && !(0, exports.isHtmlInCanvasNestingSupported)()) {
154
+ throw new Error(`Nested <HtmlInCanvas> components require Chrome ${MINIMUM_CHROME_VERSION_FOR_NESTED_HTML_IN_CANVAS} or newer with HTML-in-canvas enabled.`);
144
155
  }
145
156
  const resolvedPixelDensity = resolveHtmlInCanvasPixelDensity(pixelDensity);
146
157
  const canvasWidth = Math.ceil(width * resolvedPixelDensity);
@@ -169,6 +180,7 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
169
180
  const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
170
181
  effects,
171
182
  overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null,
183
+ videoConfigValues: (_b = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues) !== null && _b !== void 0 ? _b : null,
172
184
  });
173
185
  // Refs so the paint handler always reads fresh values.
174
186
  const effectsRef = (0, react_1.useRef)(memoizedEffects);
@@ -471,6 +483,7 @@ const HtmlInCanvasWrapped = (0, with_interactivity_schema_js_1.withInteractivity
471
483
  });
472
484
  exports.HtmlInCanvas = Object.assign(HtmlInCanvasWrapped, {
473
485
  isSupported: exports.isHtmlInCanvasSupported,
486
+ isNestingSupported: exports.isHtmlInCanvasNestingSupported,
474
487
  });
475
488
  exports.HtmlInCanvas.displayName = 'HtmlInCanvas';
476
489
  (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(exports.HtmlInCanvas);
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { LoopDisplay, SequenceControls } from './CompositionManager.js';
3
3
  import type { EffectDefinition } from './effects/effect-types.js';
4
+ import { type TimelineTrackItem } from './timeline-track-context.js';
4
5
  import type { BasicMediaInTimelineReturnType } from './use-media-in-timeline.js';
5
6
  export type AbsoluteFillLayout = {
6
7
  layout?: 'absolute-fill';
@@ -32,6 +33,10 @@ export type SequencePropsWithoutDuration = {
32
33
  readonly hidden?: boolean;
33
34
  readonly controls?: SequenceControls;
34
35
  readonly _remotionInternalEffects?: readonly EffectDefinition<unknown>[];
36
+ /**
37
+ * @deprecated For internal use only.
38
+ */
39
+ readonly _remotionInternalTimelineTrack?: Pick<TimelineTrackItem, 'role'>;
35
40
  /**
36
41
  * @deprecated For internal use only.
37
42
  */
@@ -18,19 +18,23 @@ const SequenceContext_js_1 = require("./SequenceContext.js");
18
18
  const SequenceManager_js_1 = require("./SequenceManager.js");
19
19
  const is_inside_series_js_1 = require("./series/is-inside-series.js");
20
20
  const timeline_position_state_js_1 = require("./timeline-position-state.js");
21
+ const timeline_track_context_js_1 = require("./timeline-track-context.js");
21
22
  const use_premounting_js_1 = require("./use-premounting.js");
22
23
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
23
24
  const use_sequence_registration_js_1 = require("./use-sequence-registration.js");
24
25
  const use_video_config_js_1 = require("./use-video-config.js");
25
26
  const v5_flag_js_1 = require("./v5-flag.js");
26
27
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
28
+ const SeriesContentVisibilityContext = (0, react_1.createContext)(true);
27
29
  const EMPTY_EFFECTS = [];
28
- const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playbackRate = 1, loop = false, freeze, durationInFrames, children, name, height, width, showInTimeline = true, hidden = false, controls, _remotionInternalEffects, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalDocumentationLink: documentationLink, _remotionInternalSingleChildComponent: singleChildComponent, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, outlineRef: passedRefForOutline, cropLeft, cropRight, cropTop, cropBottom, ...other }, ref) => {
29
- var _a, _b, _c, _d, _e;
30
+ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playbackRate = 1, loop = false, freeze, durationInFrames, children, name, height, width, showInTimeline = true, hidden = false, controls, _remotionInternalEffects, _remotionInternalTimelineTrack: timelineTrackItem, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalDocumentationLink: documentationLink, _remotionInternalSingleChildComponent: singleChildComponent, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, outlineRef: passedRefForOutline, cropLeft, cropRight, cropTop, cropBottom, ...other }, ref) => {
31
+ var _a, _b, _c, _d, _e, _f;
30
32
  const { layout = 'absolute-fill' } = other;
31
33
  const [id] = (0, react_1.useState)(() => String(Math.random()));
32
34
  const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
33
- const parentPlaybackRate = (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.playbackRate) !== null && _a !== void 0 ? _a : 1;
35
+ const timelineTrack = (0, react_1.useContext)(timeline_track_context_js_1.TimelineTrackContext);
36
+ const timelineTrackRole = (_a = timelineTrackItem === null || timelineTrackItem === void 0 ? void 0 : timelineTrackItem.role) !== null && _a !== void 0 ? _a : 'clip';
37
+ const parentPlaybackRate = (_b = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.playbackRate) !== null && _b !== void 0 ? _b : 1;
34
38
  const cumulativePlaybackRate = parentPlaybackRate * playbackRate;
35
39
  const cumulatedFrom = parentSequence
36
40
  ? parentSequence.cumulatedFrom + parentSequence.relativeFrom
@@ -140,7 +144,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
140
144
  const clockFrom = from + loopOffset;
141
145
  const effectiveRelativeFrom = clockFrom - trimBefore / playbackRate;
142
146
  const relativeFrom = effectiveRelativeFrom / parentPlaybackRate;
143
- const absoluteFrom = ((_b = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.absoluteFrom) !== null && _b !== void 0 ? _b : 0) + relativeFrom;
147
+ const absoluteFrom = ((_c = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.absoluteFrom) !== null && _c !== void 0 ? _c : 0) + relativeFrom;
144
148
  // Inside a loop, the local clock ends after `durationInFrames`, except in a final
145
149
  // iteration that the parent cuts short.
146
150
  const localClockEnd = loopPeriod === null
@@ -254,11 +258,18 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
254
258
  // and if it changes, it would lead to-remounting of the sequence.
255
259
  const stackRef = (0, react_1.useRef)(null);
256
260
  stackRef.current = controls
257
- ? ((_d = (_c = (0, enable_sequence_stack_traces_js_1.getStackForControls)(controls)) !== null && _c !== void 0 ? _c : stack) !== null && _d !== void 0 ? _d : null)
261
+ ? ((_e = (_d = (0, enable_sequence_stack_traces_js_1.getStackForControls)(controls)) !== null && _d !== void 0 ? _d : stack) !== null && _e !== void 0 ? _e : null)
258
262
  : (stack !== null && stack !== void 0 ? stack : null);
263
+ const getStack = (0, react_1.useCallback)(() => stackRef.current, []);
259
264
  const registeredFrozenFrame = typeof freeze === 'number' ? freeze : null;
265
+ const currentFrame = registeredFrozenFrame !== null && registeredFrozenFrame !== void 0 ? registeredFrozenFrame : (absoluteFrame - currentSequenceStart) * cumulativePlaybackRate;
266
+ const currentFrameRef = (0, react_1.useRef)(currentFrame);
267
+ (0, react_1.useLayoutEffect)(() => {
268
+ currentFrameRef.current = currentFrame;
269
+ }, [currentFrame]);
270
+ const getCurrentFrame = (0, react_1.useCallback)(() => currentFrameRef.current, []);
260
271
  const registeredTrimBefore = trimBefore === 0 ? null : trimBefore;
261
- const parentCumulatedNegativeFrom = (_e = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.cumulatedNegativeFrom) !== null && _e !== void 0 ? _e : 0;
272
+ const parentCumulatedNegativeFrom = (_f = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.cumulatedNegativeFrom) !== null && _f !== void 0 ? _f : 0;
262
273
  const startMediaFrom = isMedia && isMedia.type !== 'image'
263
274
  ? isMedia.data.startMediaFrom +
264
275
  parentCumulatedNegativeFrom -
@@ -283,6 +294,23 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
283
294
  const controlsComponentIdentity = controls === null || controls === void 0 ? void 0 : controls.componentIdentity;
284
295
  const controlsComponentName = controls === null || controls === void 0 ? void 0 : controls.componentName;
285
296
  const controlsVideoConfigValues = controls === null || controls === void 0 ? void 0 : controls.videoConfigValues;
297
+ const isInsideNonPremountFreeze = (0, freeze_js_1.useIsInsideNonPremountFreeze)();
298
+ const canInferDuration = (controlsComponentIdentity === 'dev.remotion.remotion.Series' ||
299
+ controlsComponentIdentity ===
300
+ 'dev.remotion.transitions.TransitionSeries') &&
301
+ !loop &&
302
+ registeredFrozenFrame === null &&
303
+ !isInsideNonPremountFreeze &&
304
+ !hidden;
305
+ const autoDuration = canInferDuration && durationInFrames === undefined;
306
+ const isSeriesChild = controlsComponentIdentity === 'dev.remotion.remotion.Series.Sequence' ||
307
+ controlsComponentIdentity ===
308
+ 'dev.remotion.transitions.TransitionSeries.Sequence' ||
309
+ controlsComponentIdentity ===
310
+ 'dev.remotion.transitions.TransitionSeries.Transition' ||
311
+ controlsComponentIdentity ===
312
+ 'dev.remotion.transitions.TransitionSeries.Overlay';
313
+ const seriesContentVisible = (0, react_1.useContext)(SeriesContentVisibilityContext);
286
314
  const effectRuntimeValues = (0, react_1.useMemo)(() => {
287
315
  var _a;
288
316
  return (_a = _remotionInternalEffects === null || _remotionInternalEffects === void 0 ? void 0 : _remotionInternalEffects.runtimeValues) !== null && _a !== void 0 ? _a : null;
@@ -317,9 +345,18 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
317
345
  ]);
318
346
  const getSequenceForRegistration = (0, react_1.useCallback)(() => {
319
347
  var _a, _b, _c;
348
+ const trackRegistration = timelineTrack
349
+ ? {
350
+ timelineTrack: {
351
+ ...timelineTrack,
352
+ role: timelineTrackRole,
353
+ },
354
+ }
355
+ : {};
320
356
  if (isMedia) {
321
357
  if (isMedia.type === 'image') {
322
358
  return {
359
+ ...trackRegistration,
323
360
  sequencePlaybackRate: playbackRate,
324
361
  type: 'image',
325
362
  controls: registrationControls,
@@ -338,7 +375,8 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
338
375
  showInTimeline,
339
376
  timelineOrder: null,
340
377
  src: isMedia.src,
341
- getStack: () => stackRef.current,
378
+ getStack,
379
+ getCurrentFrame,
342
380
  refForOutline: refForOutline !== null && refForOutline !== void 0 ? refForOutline : null,
343
381
  isInsideSeries,
344
382
  frozenFrame: registeredFrozenFrame,
@@ -346,6 +384,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
346
384
  };
347
385
  }
348
386
  return {
387
+ ...trackRegistration,
349
388
  type: isMedia.type,
350
389
  sequencePlaybackRate: playbackRate,
351
390
  controls: registrationControls,
@@ -366,7 +405,8 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
366
405
  showInTimeline,
367
406
  timelineOrder: null,
368
407
  src: isMedia.data.src,
369
- getStack: () => stackRef.current,
408
+ getStack,
409
+ getCurrentFrame,
370
410
  startMediaFrom: startMediaFrom !== null && startMediaFrom !== void 0 ? startMediaFrom : isMedia.data.startMediaFrom,
371
411
  mediaFrameAtSequenceZero,
372
412
  volume: isMedia.data.volumes,
@@ -379,10 +419,14 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
379
419
  };
380
420
  }
381
421
  return {
422
+ ...trackRegistration,
382
423
  from,
383
424
  sequencePlaybackRate: playbackRate,
384
425
  trimBefore: registeredTrimBefore,
385
426
  duration: actualDurationInFrames,
427
+ ...(autoDuration ? { autoDuration: true } : {}),
428
+ ...(canInferDuration ? { canInferDuration: true } : {}),
429
+ ...(isSeriesChild ? { unclippedDuration: effectiveDurationInFrames } : {}),
386
430
  id,
387
431
  displayName: timelineClipName,
388
432
  documentationLink: resolvedDocumentationLink,
@@ -391,7 +435,8 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
391
435
  showInTimeline,
392
436
  timelineOrder: null,
393
437
  loopDisplay: resolvedLoopDisplay,
394
- getStack: () => stackRef.current,
438
+ getStack,
439
+ getCurrentFrame,
395
440
  premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
396
441
  postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
397
442
  controls: registrationControls,
@@ -404,10 +449,18 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
404
449
  };
405
450
  }, [
406
451
  id,
452
+ timelineTrack,
453
+ timelineTrackRole,
454
+ getCurrentFrame,
455
+ getStack,
407
456
  timelineClipName,
408
457
  playbackRate,
409
458
  parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id,
410
459
  actualDurationInFrames,
460
+ autoDuration,
461
+ canInferDuration,
462
+ isSeriesChild,
463
+ effectiveDurationInFrames,
411
464
  from,
412
465
  registeredTrimBefore,
413
466
  showInTimeline,
@@ -442,7 +495,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
442
495
  parentPlaybackRate,
443
496
  durationInFrames: effectiveDurationInFrames,
444
497
  });
445
- const content = frameInParent - from < -boundaryTolerance
498
+ const content = !seriesContentVisible || frameInParent - from < -boundaryTolerance
446
499
  ? null
447
500
  : frameInParent - endThreshold >= -boundaryTolerance
448
501
  ? null
@@ -485,7 +538,16 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playba
485
538
  if (hidden) {
486
539
  return shouldDiscoverOutline ? (jsx_runtime_1.jsx(sequence_order_marker_js_1.SequenceOrderMarker, { sequenceId: id, outlineChildrenRef: automaticOutlineRef, children: null })) : null;
487
540
  }
488
- const sequence = (jsx_runtime_1.jsx(SequenceContext_js_1.SequenceContext.Provider, { value: contextValue, children: loopedContent === null ? null : other.layout === 'none' ? (loopedContent) : (jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: sequenceRef, style: defaultStyle, className: other.className, children: loopedContent })) }));
541
+ // Retain resolved scene registrations so Studio can recover the natural end
542
+ // even when seeking past an explicit wrapper trim. Scene contents stay hidden.
543
+ const retainSeriesRegistration = env.isStudio && canInferDuration;
544
+ const renderedContent = loopedContent === null ? (retainSeriesRegistration ? (children) : null) : other.layout === 'none' ? (loopedContent) : (jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: sequenceRef, style: defaultStyle, className: other.className, children: loopedContent }));
545
+ const sequenceContent = (jsx_runtime_1.jsx(SequenceContext_js_1.SequenceContext.Provider, { value: contextValue, children: retainSeriesRegistration ? (jsx_runtime_1.jsx(SeriesContentVisibilityContext.Provider, { value: content !== null, children: renderedContent })) : (renderedContent) }));
546
+ // Keep the provider mounted when track grouping changes so clip state survives.
547
+ const sequence = (jsx_runtime_1.jsx(timeline_track_context_js_1.TimelineTrackContext.Provider, { value: timelineTrackRole === 'track' ||
548
+ (timelineTrackRole === 'clip' && !showInTimeline)
549
+ ? timelineTrack
550
+ : null, children: sequenceContent }));
489
551
  return shouldDiscoverOutline ? (jsx_runtime_1.jsx(sequence_order_marker_js_1.SequenceOrderMarker, { sequenceId: id, outlineChildrenRef: automaticOutlineRef, children: sequence })) : (sequence);
490
552
  };
491
553
  const RegularSequence = (0, react_1.forwardRef)(RegularSequenceRefForwardingFunction);
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { TSequence } from './CompositionManager.js';
3
3
  import type { CanUpdateSequencePropStatus, DragOverrideValue, GetDragOverrides, GetEffectDragOverrides, PropStatuses } from './use-schema.js';
4
+ import type { SourceNumericValue } from './use-schema.js';
4
5
  import type { VideoConfigValues } from './video-config.js';
5
6
  export type SequenceManagerContext = {
6
7
  registerSequence: (seq: TSequence) => void;
@@ -12,7 +13,10 @@ export type SequenceManagerRef = {
12
13
  current: TSequence[];
13
14
  };
14
15
  export type SequenceNodePath = Array<string | number>;
16
+ type SequenceManagerActions = Pick<SequenceManagerContext, 'registerSequence' | 'updateSequence' | 'unregisterSequence'>;
17
+ export declare const SequenceManagerActionsContext: React.Context<SequenceManagerActions>;
15
18
  export declare const SequenceManager: React.Context<SequenceManagerContext>;
19
+ export declare const useSequenceManagerSequences: () => TSequence[];
16
20
  export declare const SequenceManagerRefContext: React.Context<SequenceManagerRef>;
17
21
  export declare const SequenceRegistrationContext: React.Context<boolean>;
18
22
  export declare const DisableSequenceRegistrationContext: React.Context<boolean>;
@@ -29,6 +33,14 @@ export type VisualModeDragOverrides = {
29
33
  getDragOverrides: GetDragOverrides;
30
34
  getEffectDragOverrides: GetEffectDragOverrides;
31
35
  };
36
+ type DragOverridesSubscription = {
37
+ manager: SequenceManagerActions;
38
+ subscribe: (key: string | null, listener: () => void) => () => void;
39
+ getSnapshot: (key: string | null) => Record<string, DragOverrideValue>;
40
+ subscribeEffects: (key: string | null, listener: () => void) => () => void;
41
+ getEffectSnapshot: (key: string | null) => Record<string, Record<string, DragOverrideValue>>;
42
+ };
43
+ export declare const VisualModeDragOverridesSubscriptionContext: React.Context<DragOverridesSubscription | null>;
32
44
  export type SequencePropsStatusRemapping = {
33
45
  previousNodePath: SequencePropsSubscriptionKey;
34
46
  nodePath: SequencePropsSubscriptionKey | null;
@@ -42,12 +54,25 @@ export type VisualModeSetters = {
42
54
  setPropStatuses: (nodePath: SequencePropsSubscriptionKey, values: (prev: CanUpdateSequencePropsResponse) => CanUpdateSequencePropsResponse) => void;
43
55
  remapPropStatuses: (remappings: readonly SequencePropsStatusRemapping[]) => void;
44
56
  };
45
- export type CanUpdateEffectPropsResponseTrue = {
57
+ export type VisualModeBatchSetters = {
58
+ setDragOverridesBatch: (overrides: readonly {
59
+ readonly nodePath: SequencePropsSubscriptionKey;
60
+ readonly key: string;
61
+ readonly value: DragOverrideValue;
62
+ }[]) => void;
63
+ setEffectDragOverridesBatch: (overrides: readonly {
64
+ readonly nodePath: SequencePropsSubscriptionKey;
65
+ readonly effectIndex: number;
66
+ readonly key: string;
67
+ readonly value: DragOverrideValue;
68
+ }[]) => void;
69
+ };
70
+ export type CanUpdateEffectPropsResponseTrue<Numeric = SourceNumericValue> = {
46
71
  canUpdate: true;
47
72
  callee: string;
48
73
  importPath: string | null;
49
74
  effectIndex: number;
50
- props: Record<string, CanUpdateSequencePropStatus>;
75
+ props: Record<string, CanUpdateSequencePropStatus<Numeric>>;
51
76
  };
52
77
  export type CannotUpdateEffectReason = 'not-found' | 'computed' | 'not-call-expression';
53
78
  export type CannotUpdateSequenceReason = 'not-found' | 'error';
@@ -56,27 +81,32 @@ export type CanUpdateEffectPropsResponseFalse = {
56
81
  effectIndex: number;
57
82
  reason: CannotUpdateEffectReason;
58
83
  };
59
- export type CanUpdateEffectPropsResponse = CanUpdateEffectPropsResponseTrue | CanUpdateEffectPropsResponseFalse;
60
- export type CanUpdateSequencePropsResponseTrue = {
84
+ export type CanUpdateEffectPropsResponse<Numeric = SourceNumericValue> = CanUpdateEffectPropsResponseTrue<Numeric> | CanUpdateEffectPropsResponseFalse;
85
+ export type CanUpdateSequencePropsResponseTrue<Numeric = SourceNumericValue> = {
61
86
  canUpdate: true;
62
- props: Record<string, CanUpdateSequencePropStatus>;
63
- effects: CanUpdateEffectPropsResponse[];
87
+ props: Record<string, CanUpdateSequencePropStatus<Numeric>>;
88
+ effects: CanUpdateEffectPropsResponse<Numeric>[];
64
89
  };
65
90
  export type CanUpdateSequencePropsResponseFalse = {
66
91
  canUpdate: false;
67
92
  reason: CannotUpdateSequenceReason;
68
93
  };
69
- export type CanUpdateSequencePropsResponse = CanUpdateSequencePropsResponseTrue | CanUpdateSequencePropsResponseFalse;
94
+ export type CanUpdateSequencePropsResponse<Numeric = SourceNumericValue> = CanUpdateSequencePropsResponseTrue<Numeric> | CanUpdateSequencePropsResponseFalse;
70
95
  export declare const makeSequencePropsSubscriptionKey: (key: SequencePropsSubscriptionKey) => string;
71
96
  export declare const VisualModePropStatusesContext: React.Context<VisualModePropStatuses>;
72
97
  export declare const VisualModePropStatusesRefContext: React.Context<VisualModePropStatusesRef>;
73
98
  export declare const VisualModeDragOverridesContext: React.Context<VisualModeDragOverrides>;
99
+ export declare const useDragOverridesForNodePath: (nodePath: SequencePropsSubscriptionKey | null) => Record<string, DragOverrideValue>;
100
+ export declare const useActiveFromDragOverrideKeys: () => ReadonlySet<string>;
101
+ export declare const useEffectDragOverridesForNodePath: (nodePath: SequencePropsSubscriptionKey | null, effectCount: number) => Record<string, Record<string, DragOverrideValue>>;
74
102
  export declare const VisualModeSettersContext: React.Context<VisualModeSetters>;
103
+ export declare const VisualModeBatchSettersContext: React.Context<VisualModeBatchSetters | null>;
75
104
  export type SequencePropsSubscriptionKey = {
76
105
  absolutePath: string;
77
106
  nodePath: SequenceNodePath;
78
107
  sequenceKeys: string[];
79
108
  effectKeys: string[][];
109
+ /** Evaluation context of a rendered instance. Never part of source identity. */
80
110
  videoConfigValues: VideoConfigValues | null;
81
111
  };
82
112
  export type { VideoConfigValues } from './video-config.js';