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
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OptimisticSequenceDeletion = exports.usePendingSequenceDeletions = void 0;
4
+ const react_1 = require("react");
5
+ const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
6
+ const use_sync_external_store_js_1 = require("./use-sync-external-store.js");
7
+ const deletions = new Map();
8
+ const stackToNode = new Map();
9
+ const listeners = new Set();
10
+ const empty = new Set();
11
+ let snapshot = empty;
12
+ const keyForNode = (node) => JSON.stringify([node.absolutePath, node.nodePath]);
13
+ const publish = (force = false) => {
14
+ const next = new Set([...deletions].filter(([, value]) => value.deleted).map(([key]) => key));
15
+ if (!force &&
16
+ next.size === snapshot.size &&
17
+ [...next].every((key) => snapshot.has(key))) {
18
+ return;
19
+ }
20
+ snapshot = next.size === 0 ? empty : next;
21
+ for (const listener of listeners) {
22
+ listener();
23
+ }
24
+ };
25
+ const subscribe = (listener) => {
26
+ listeners.add(listener);
27
+ return () => {
28
+ listeners.delete(listener);
29
+ };
30
+ };
31
+ const usePendingSequenceDeletions = () => {
32
+ const environment = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
33
+ const value = (0, use_sync_external_store_js_1.useSyncExternalStore)(subscribe, () => snapshot, () => empty);
34
+ return environment.isStudio && !environment.isRendering ? value : empty;
35
+ };
36
+ exports.usePendingSequenceDeletions = usePendingSequenceDeletions;
37
+ exports.OptimisticSequenceDeletion = {
38
+ register: (stack, node) => {
39
+ if (stack === null || node === null) {
40
+ return;
41
+ }
42
+ const key = keyForNode(node);
43
+ if (stackToNode.get(stack) === key) {
44
+ return;
45
+ }
46
+ stackToNode.set(stack, key);
47
+ if (snapshot.size > 0) {
48
+ publish(true);
49
+ }
50
+ },
51
+ isDeleted: (node, pending) => node !== null && pending.has(keyForNode(node)),
52
+ isElementDeleted: (element, pending) => {
53
+ if (!(0, react_1.isValidElement)(element)) {
54
+ return false;
55
+ }
56
+ const stack = element.props._remotionInternalStack;
57
+ const key = stack === undefined ? undefined : stackToNode.get(stack);
58
+ return key !== undefined && pending.has(key);
59
+ },
60
+ set: (nodes, revision, deleted) => {
61
+ for (const node of nodes) {
62
+ const key = keyForNode(node);
63
+ const previous = deletions.get(key);
64
+ if (previous && previous.revision > revision) {
65
+ continue;
66
+ }
67
+ deletions.set(key, { id: revision, revision, deleted });
68
+ }
69
+ publish();
70
+ },
71
+ rollback: (nodes, revision) => {
72
+ var _a;
73
+ for (const node of nodes) {
74
+ const key = keyForNode(node);
75
+ if (((_a = deletions.get(key)) === null || _a === void 0 ? void 0 : _a.revision) === revision) {
76
+ deletions.delete(key);
77
+ }
78
+ }
79
+ publish();
80
+ },
81
+ // Undo/redo can only update deletions still represented by the loaded tree.
82
+ // Once source remapping retires them, restoration is handled by HMR.
83
+ restore: (nodes, revision, deleted) => {
84
+ for (const node of nodes) {
85
+ const key = keyForNode(node);
86
+ const previous = deletions.get(key);
87
+ if (previous && previous.revision <= revision) {
88
+ deletions.set(key, { ...previous, revision, deleted });
89
+ }
90
+ }
91
+ publish();
92
+ },
93
+ prepareRetirement: (nodes, dispatchedRevision) => {
94
+ const captured = nodes.map((node) => {
95
+ var _a;
96
+ const key = keyForNode(node);
97
+ return { key, id: (_a = deletions.get(key)) === null || _a === void 0 ? void 0 : _a.id };
98
+ });
99
+ return () => {
100
+ var _a;
101
+ let changed = false;
102
+ for (const { key, id } of captured) {
103
+ if (id !== undefined &&
104
+ id <= dispatchedRevision &&
105
+ ((_a = deletions.get(key)) === null || _a === void 0 ? void 0 : _a.id) === id) {
106
+ changed = deletions.delete(key) || changed;
107
+ }
108
+ }
109
+ if (changed) {
110
+ publish();
111
+ }
112
+ };
113
+ },
114
+ };
@@ -0,0 +1,17 @@
1
+ export type RegistryStore<TSnapshot> = {
2
+ readonly getSnapshot: () => TSnapshot;
3
+ readonly subscribe: (listener: () => void) => () => void;
4
+ readonly setSnapshot: (update: (previous: TSnapshot) => TSnapshot) => void;
5
+ };
6
+ export declare const areRegistryEntriesEqual: <T extends object>(previous: T, next: T) => boolean;
7
+ export declare const reconcileRegistryEntries: <T extends object>({ current, entries, previousDescriptors, previousKeys, nextKeys, getKey, order, orderProperty, }: {
8
+ readonly current: T[];
9
+ readonly entries: readonly T[];
10
+ readonly previousDescriptors: ReadonlyMap<string, unknown>;
11
+ readonly previousKeys: ReadonlySet<string>;
12
+ readonly nextKeys: ReadonlySet<string>;
13
+ readonly getKey: (entry: T) => string;
14
+ readonly order: ReadonlyMap<string, number>;
15
+ readonly orderProperty: keyof T;
16
+ }) => T[];
17
+ export declare const createRegistryStore: <TSnapshot>(initialSnapshot: TSnapshot) => RegistryStore<TSnapshot>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRegistryStore = exports.reconcileRegistryEntries = exports.areRegistryEntriesEqual = void 0;
4
+ const areRegistryEntriesEqual = (previous, next) => {
5
+ const keys = Object.keys(previous);
6
+ return (keys.length === Object.keys(next).length &&
7
+ keys.every((key) => Object.prototype.hasOwnProperty.call(next, key) &&
8
+ Object.is(Reflect.get(previous, key), Reflect.get(next, key))));
9
+ };
10
+ exports.areRegistryEntriesEqual = areRegistryEntriesEqual;
11
+ const reconcileRegistryEntries = ({ current, entries, previousDescriptors, previousKeys, nextKeys, getKey, order, orderProperty, }) => {
12
+ var _a;
13
+ const previousByKey = new Map(current.map((entry) => [getKey(entry), entry]));
14
+ const next = entries.map((entry) => {
15
+ var _a;
16
+ const key = getKey(entry);
17
+ const previous = previousByKey.get(key);
18
+ const nextOrder = (_a = order.get(key)) !== null && _a !== void 0 ? _a : null;
19
+ if (previous &&
20
+ previousDescriptors.get(key) === entry &&
21
+ previous[orderProperty] === nextOrder) {
22
+ return previous;
23
+ }
24
+ const registered = { ...entry, [orderProperty]: nextOrder };
25
+ return previous && (0, exports.areRegistryEntriesEqual)(previous, registered)
26
+ ? previous
27
+ : registered;
28
+ });
29
+ // Preserve imperative registrations, including their committed order.
30
+ for (const entry of current) {
31
+ const key = getKey(entry);
32
+ if (!previousKeys.has(key) && !nextKeys.has(key)) {
33
+ const nextOrder = (_a = order.get(key)) !== null && _a !== void 0 ? _a : entry[orderProperty];
34
+ next.push(entry[orderProperty] === nextOrder
35
+ ? entry
36
+ : { ...entry, [orderProperty]: nextOrder });
37
+ }
38
+ }
39
+ return next.length === current.length &&
40
+ next.every((entry, index) => entry === current[index])
41
+ ? current
42
+ : next;
43
+ };
44
+ exports.reconcileRegistryEntries = reconcileRegistryEntries;
45
+ const createRegistryStore = (initialSnapshot) => {
46
+ let snapshot = initialSnapshot;
47
+ const listeners = new Set();
48
+ return {
49
+ getSnapshot: () => snapshot,
50
+ subscribe: (listener) => {
51
+ listeners.add(listener);
52
+ return () => {
53
+ listeners.delete(listener);
54
+ };
55
+ },
56
+ setSnapshot: (update) => {
57
+ const next = update(snapshot);
58
+ if (next === snapshot) {
59
+ return;
60
+ }
61
+ snapshot = next;
62
+ for (const listener of [...listeners]) {
63
+ listener();
64
+ }
65
+ },
66
+ };
67
+ };
68
+ exports.createRegistryStore = createRegistryStore;
@@ -0,0 +1,13 @@
1
+ import type { TimelineContextValue } from './TimelineContext.js';
2
+ export { DEFAULT_SEQUENCE_ACTIVITY_LIMIT } from './sequence-activity-defaults.js';
3
+ export declare const SequenceActivityContext: import("react").Context<boolean>;
4
+ export declare const SequenceActivityDormantContext: import("react").Context<boolean>;
5
+ export declare const SequenceActivitySettingsContext: import("react").Context<{
6
+ readonly enabled: boolean;
7
+ readonly limit: number;
8
+ } | null>;
9
+ export declare const SequenceActivityTimelineContext: import("react").Context<TimelineContextValue | null>;
10
+ export declare const SequenceActivityAbsoluteTimeContext: import("react").Context<TimelineContextValue | null>;
11
+ export declare const SequenceContent: React.FC<{
12
+ readonly children: React.ReactNode;
13
+ }>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SequenceContent = exports.SequenceActivityAbsoluteTimeContext = exports.SequenceActivityTimelineContext = exports.SequenceActivitySettingsContext = exports.SequenceActivityDormantContext = exports.SequenceActivityContext = exports.DEFAULT_SEQUENCE_ACTIVITY_LIMIT = void 0;
4
+ const react_1 = require("react");
5
+ const sequence_activity_defaults_js_1 = require("./sequence-activity-defaults.js");
6
+ Object.defineProperty(exports, "DEFAULT_SEQUENCE_ACTIVITY_LIMIT", { enumerable: true, get: function () { return sequence_activity_defaults_js_1.DEFAULT_SEQUENCE_ACTIVITY_LIMIT; } });
7
+ // Internal Studio experiment. Hidden Activity trees register on commit, so the
8
+ // experiment is disabled when the sequence manager falls back to effects.
9
+ exports.SequenceActivityContext = (0, react_1.createContext)(false);
10
+ exports.SequenceActivityDormantContext = (0, react_1.createContext)(false);
11
+ exports.SequenceActivitySettingsContext = (0, react_1.createContext)(null);
12
+ // React propagates changed ancestor contexts through hidden Activity trees,
13
+ // even when a nested provider keeps their value stable. Use separate context
14
+ // identities so dormant clocks do not subscribe to the advancing timeline.
15
+ exports.SequenceActivityTimelineContext = (0, react_1.createContext)(null);
16
+ exports.SequenceActivityAbsoluteTimeContext = (0, react_1.createContext)(null);
17
+ const SequenceContent = ({ children }) => {
18
+ return (0, react_1.useContext)(exports.SequenceActivityDormantContext) ? null : children;
19
+ };
20
+ exports.SequenceContent = SequenceContent;
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_SEQUENCE_ACTIVITY_LIMIT = 20;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_SEQUENCE_ACTIVITY_LIMIT = void 0;
4
+ exports.DEFAULT_SEQUENCE_ACTIVITY_LIMIT = 20;
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SequenceOutlineInternals = exports.SequenceOutlineContext = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  exports.SequenceOutlineContext = react_1.default.createContext(false);
9
- // Keep automatic groups separate from the public, single-element outlineRef.
10
9
  // A group only exposes .current when it has exactly one element, so consumers
11
10
  // that require an actual element never accidentally act on part of a group.
12
11
  const nodesByRef = new WeakMap();
@@ -26,10 +25,10 @@ exports.SequenceOutlineInternals = {
26
25
  previous.every((node, index) => node === nodes[index])) {
27
26
  return;
28
27
  }
29
- nodesByRef.set(ref, nodes);
30
28
  ref.current =
31
29
  nodes.length === 1 && nodes[0].nodeType === 1
32
30
  ? nodes[0]
33
31
  : null;
32
+ nodesByRef.set(ref, nodes);
34
33
  },
35
34
  };
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { TSequence } from './CompositionManager.js';
3
+ import type { RegistryStore } from './registry-store.js';
4
+ export type SequenceManagerActions = {
5
+ registerSequence: (seq: TSequence) => void;
6
+ updateSequence: (seq: TSequence) => void;
7
+ unregisterSequence: (id: string) => void;
8
+ };
9
+ export type SequenceManagerRef = {
10
+ current: TSequence[];
11
+ };
12
+ export type SequenceNodePath = Array<string | number>;
13
+ export declare const SequenceManagerActionsContext: React.Context<SequenceManagerActions>;
14
+ export declare const SequenceRegistryContext: React.Context<RegistryStore<TSequence[]> | null>;
15
+ export declare const SequenceCommitRegistrationContext: React.Context<boolean>;
16
+ export declare const SequenceRegistryScopeContext: React.Context<{
17
+ readonly commitRegistrationRequested: boolean;
18
+ readonly onCommitSequences: (scopeId: string, sequences: readonly TSequence[], sequenceIds: readonly string[]) => void;
19
+ } | null>;
20
+ export declare const useSequenceManagerSequences: () => TSequence[];
21
+ export declare const SequenceManagerRefContext: React.Context<SequenceManagerRef>;
22
+ export declare const SequenceRegistrationContext: React.Context<boolean>;
23
+ export declare const DisableSequenceRegistrationContext: React.Context<boolean>;
24
+ export declare const DisableSequenceRegistrationProvider: React.FC<{
25
+ readonly children: React.ReactNode;
26
+ }>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DisableSequenceRegistrationProvider = exports.DisableSequenceRegistrationContext = exports.SequenceRegistrationContext = exports.SequenceManagerRefContext = exports.useSequenceManagerSequences = exports.SequenceRegistryScopeContext = exports.SequenceCommitRegistrationContext = exports.SequenceRegistryContext = exports.SequenceManagerActionsContext = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const use_sync_external_store_js_1 = require("./use-sync-external-store.js");
39
+ const defaultSequenceManagerActions = {
40
+ registerSequence: () => {
41
+ throw new Error('SequenceManagerActionsContext not initialized');
42
+ },
43
+ updateSequence: () => {
44
+ throw new Error('SequenceManagerActionsContext not initialized');
45
+ },
46
+ unregisterSequence: () => {
47
+ throw new Error('SequenceManagerActionsContext not initialized');
48
+ },
49
+ };
50
+ exports.SequenceManagerActionsContext = react_1.default.createContext(defaultSequenceManagerActions);
51
+ exports.SequenceRegistryContext = react_1.default.createContext(null);
52
+ const subscribeToNoRegistry = () => () => undefined;
53
+ const emptySequences = [];
54
+ const getEmptySequences = () => emptySequences;
55
+ exports.SequenceCommitRegistrationContext = react_1.default.createContext(false);
56
+ exports.SequenceRegistryScopeContext = react_1.default.createContext(null);
57
+ const useSequenceManagerSequences = () => {
58
+ var _a, _b, _c;
59
+ const registry = (0, react_1.useContext)(exports.SequenceRegistryContext);
60
+ return (0, use_sync_external_store_js_1.useSyncExternalStore)((_a = registry === null || registry === void 0 ? void 0 : registry.subscribe) !== null && _a !== void 0 ? _a : subscribeToNoRegistry, (_b = registry === null || registry === void 0 ? void 0 : registry.getSnapshot) !== null && _b !== void 0 ? _b : getEmptySequences, (_c = registry === null || registry === void 0 ? void 0 : registry.getSnapshot) !== null && _c !== void 0 ? _c : getEmptySequences);
61
+ };
62
+ exports.useSequenceManagerSequences = useSequenceManagerSequences;
63
+ exports.SequenceManagerRefContext = react_1.default.createContext({
64
+ current: [],
65
+ });
66
+ exports.SequenceRegistrationContext = react_1.default.createContext(false);
67
+ exports.DisableSequenceRegistrationContext = react_1.default.createContext(false);
68
+ const DisableSequenceRegistrationProvider = ({ children }) => {
69
+ return react_1.default.createElement(exports.DisableSequenceRegistrationContext.Provider, { value: true }, children);
70
+ };
71
+ exports.DisableSequenceRegistrationProvider = DisableSequenceRegistrationProvider;
@@ -1,12 +1,13 @@
1
1
  import React, { type PropsWithChildren } from 'react';
2
2
  import type { LayoutAndStyle, SequenceProps } from '../Sequence.js';
3
+ import { type TrackWithoutSchemaProps } from '../Track.js';
3
4
  type SeriesSequenceProps = PropsWithChildren<{
4
5
  readonly durationInFrames: number;
5
6
  readonly offset?: number;
6
7
  readonly className?: string;
7
8
  } & Pick<SequenceProps, 'layout' | 'name' | 'hidden' | 'showInTimeline' | 'freeze' | 'trimBefore' | 'playbackRate'> & LayoutAndStyle>;
8
9
  declare const SeriesSequence: React.ForwardRefExoticComponent<SeriesSequenceProps & React.RefAttributes<HTMLDivElement>>;
9
- type SeriesProps = SequenceProps;
10
+ type SeriesProps = TrackWithoutSchemaProps;
10
11
  /**
11
12
  * @description with this component, you can easily stitch together scenes that should play sequentially after another.
12
13
  * @see [Documentation](https://www.remotion.dev/docs/series)
@@ -39,6 +39,7 @@ const react_1 = __importStar(require("react"));
39
39
  const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js");
40
40
  const Interactive_js_1 = require("../Interactive.js");
41
41
  const interactivity_schema_js_1 = require("../interactivity-schema.js");
42
+ const optimistic_sequence_deletion_js_1 = require("../optimistic-sequence-deletion.js");
42
43
  const Sequence_js_1 = require("../Sequence.js");
43
44
  const Track_js_1 = require("../Track.js");
44
45
  const validate_duration_in_frames_js_1 = require("../validation/validate-duration-in-frames.js");
@@ -92,8 +93,9 @@ const validateSeriesSequenceProps = ({ durationInFrames, offset: offsetProp, ind
92
93
  };
93
94
  const SeriesInner = (props) => {
94
95
  var _a;
96
+ const pendingDeletions = (0, optimistic_sequence_deletion_js_1.usePendingSequenceDeletions)();
95
97
  const childrenValue = (0, react_1.useMemo)(() => {
96
- const flattenedChildren = (0, flatten_children_js_1.flattenChildren)(props.children);
98
+ const flattenedChildren = (0, flatten_children_js_1.flattenChildren)(props.children).filter((child) => !optimistic_sequence_deletion_js_1.OptimisticSequenceDeletion.isElementDeleted(child, pendingDeletions));
97
99
  const renderChildren = (i, startFrame) => {
98
100
  if (i === flattenedChildren.length) {
99
101
  return null;
@@ -135,12 +137,15 @@ const SeriesInner = (props) => {
135
137
  const currentStartFrame = startFrame + offset;
136
138
  const nextStartFrame = startFrame + timelineDurationInFrames + offset;
137
139
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
138
- jsx_runtime_1.jsx(SequenceWithoutSchemaWithRef, { ref: ref, name: name || '<Series.Sequence>', _remotionInternalDocumentationLink: name ? undefined : 'https://www.remotion.dev/docs/series', controls: controls !== null && controls !== void 0 ? controls : undefined, from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, _remotionInternalSingleChildComponent: (0, enable_sequence_stack_traces_js_1.getSingleChildComponent)(sequenceChildren), children: jsx_runtime_1.jsx(is_inside_series_js_1.IsNotInsideSeriesProvider, { children: sequenceChildren }) }), renderChildren(i + 1, nextStartFrame)] }));
140
+ jsx_runtime_1.jsx(SequenceWithoutSchemaWithRef, { ref: ref, name: name || '<Series.Sequence>', _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series", controls: controls !== null && controls !== void 0 ? controls : undefined, from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, _remotionInternalTimelineTrack: {
141
+ role: 'clip',
142
+ seriesOffset: offset,
143
+ }, children: jsx_runtime_1.jsx(is_inside_series_js_1.IsNotInsideSeriesProvider, { children: sequenceChildren }) }), renderChildren(i + 1, nextStartFrame)] }));
139
144
  },
140
145
  });
141
146
  };
142
147
  return renderChildren(0, 0);
143
- }, [props.children]);
148
+ }, [props.children, pendingDeletions]);
144
149
  return (jsx_runtime_1.jsx(Track_js_1.TrackWithoutSchema, { layout: "none", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series", ...props, name: (_a = props.name) !== null && _a !== void 0 ? _a : '<Series>', children: jsx_runtime_1.jsx(is_inside_series_js_1.IsInsideSeriesContainer, { children: childrenValue }) }));
145
150
  };
146
151
  /**
@@ -151,7 +156,10 @@ const Series = Object.assign((0, with_interactivity_schema_js_1.withInteractivit
151
156
  Component: SeriesInner,
152
157
  componentName: '<Series>',
153
158
  componentIdentity: 'dev.remotion.remotion.Series',
154
- schema: interactivity_schema_js_1.sequenceSchemaDefaultLayoutNone,
159
+ schema: {
160
+ ...interactivity_schema_js_1.sequenceSchemaDefaultLayoutNone,
161
+ ...interactivity_schema_js_1.sequenceTimingSchema,
162
+ },
155
163
  supportsEffects: false,
156
164
  }), {
157
165
  Sequence: SeriesSequence,
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useBuffering = exports.usePlaying = exports.useTimelineSeekFrame = exports.useTimelineSetFrameWithoutSeek = exports.useAbsoluteTimelinePosition = exports.useIsInsideFreeze = exports.useTimelinePosition = exports.usePlaybackRate = exports.useTimelineContext = exports.clampFrameToCompositionRange = exports.getFrameForComposition = exports.getInitialFrameState = exports.persistCurrentFrame = void 0;
4
4
  const react_1 = require("react");
5
+ const sequence_activity_context_js_1 = require("./sequence-activity-context.js");
5
6
  const TimelineContext_js_1 = require("./TimelineContext.js");
6
7
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
7
8
  const use_video_js_1 = require("./use-video.js");
@@ -40,16 +41,22 @@ const useTimelinePositionFromContext = (state) => {
40
41
  var _a, _b;
41
42
  const videoConfig = (0, use_video_js_1.useVideo)();
42
43
  const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
44
+ const dormant = (0, react_1.useContext)(sequence_activity_context_js_1.SequenceActivityDormantContext);
43
45
  if (!videoConfig) {
44
46
  return typeof window === 'undefined'
45
47
  ? 0
46
48
  : ((_a = window.remotion_initialFrame) !== null && _a !== void 0 ? _a : 0);
47
49
  }
48
50
  const unclamped = (_b = state.frame[videoConfig.id]) !== null && _b !== void 0 ? _b : (env.isPlayer ? 0 : (0, exports.getFrameForComposition)(videoConfig.id));
49
- return (0, exports.clampFrameToCompositionRange)(unclamped, videoConfig.durationInFrames);
51
+ // A discovery clock can be beyond the composition end, for example when a
52
+ // nested scene is trimmed by its parent. Keep its initial local frame intact.
53
+ return dormant
54
+ ? unclamped
55
+ : (0, exports.clampFrameToCompositionRange)(unclamped, videoConfig.durationInFrames);
50
56
  };
51
57
  const useTimelineContext = () => {
52
- const state = (0, react_1.useContext)(TimelineContext_js_1.TimelineContext);
58
+ const dormant = (0, react_1.useContext)(sequence_activity_context_js_1.SequenceActivityDormantContext);
59
+ const state = (0, react_1.useContext)(dormant ? sequence_activity_context_js_1.SequenceActivityTimelineContext : TimelineContext_js_1.TimelineContext);
53
60
  if (state === null) {
54
61
  throw new Error('TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.');
55
62
  }
@@ -74,7 +81,8 @@ const useIsInsideFreeze = () => {
74
81
  };
75
82
  exports.useIsInsideFreeze = useIsInsideFreeze;
76
83
  const useAbsoluteTimelinePosition = () => {
77
- const state = (0, react_1.useContext)(TimelineContext_js_1.AbsoluteTimeContext);
84
+ const dormant = (0, react_1.useContext)(sequence_activity_context_js_1.SequenceActivityDormantContext);
85
+ const state = (0, react_1.useContext)(dormant ? sequence_activity_context_js_1.SequenceActivityAbsoluteTimeContext : TimelineContext_js_1.AbsoluteTimeContext);
78
86
  if (state === null) {
79
87
  throw new Error('AbsoluteTimeContext is not available. This hook must be used inside a <Player> or the Remotion Studio.');
80
88
  }
@@ -4,6 +4,7 @@ export type TimelineTrack = {
4
4
  };
5
5
  export type TimelineTrackItem = TimelineTrack & {
6
6
  readonly role: 'track' | 'clip' | 'transition' | 'overlay';
7
+ readonly seriesOffset: number | null;
7
8
  };
8
9
  export declare const TimelineTrackContext: import("react").Context<TimelineTrack | null>;
9
10
  export declare const ExperimentalTracksEnabledContext: import("react").Context<boolean>;
@@ -35,9 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.useLazyComponent = void 0;
37
37
  const react_1 = __importStar(require("react"));
38
+ const registry_store_js_1 = require("./registry-store.js");
39
+ const use_sync_external_store_js_1 = require("./use-sync-external-store.js");
40
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? react_1.useEffect : react_1.useLayoutEffect;
38
41
  // Expected, it can be any component props
39
42
  const useLazyComponent = ({ compProps, componentName, noSuspense, }) => {
40
- // Why a ref + stable wrapper instead of returning compProps.component directly?
43
+ // Why a store + stable wrapper instead of returning compProps.component directly?
41
44
  //
42
45
  // When a user edits their component and saves, React Fast Refresh re-executes
43
46
  // the module, giving compProps.component a new function reference.
@@ -46,29 +49,41 @@ const useLazyComponent = ({ compProps, componentName, noSuspense, }) => {
46
49
  // rendered `<Comp />` where Comp had a different identity, so React unmounted
47
50
  // the old tree and mounted a fresh one — losing all component state.
48
51
  //
49
- // To fix this, we store the latest component in a ref (updated every render)
50
- // and return a stable Wrapper from useMemo (created once). React sees the same
51
- // Wrapper component across Fast Refresh updates, preserves the tree and state,
52
- // while the ref ensures the Wrapper always delegates to the latest code.
52
+ // A stable Wrapper preserves the tree across Fast Refresh updates. Publish its
53
+ // implementation on commit so an abandoned render cannot change the component
54
+ // exposed by an already registered composition. The subscription updates mounted
55
+ // wrappers even when the registration's component identity stays the same.
53
56
  //
54
57
  // To reproduce: use packages/example/src/NewVideo.tsx, edit Component
55
58
  // (e.g. change volume={1} to volume={2}) and save. Without this fix,
56
59
  // Component would fully remount instead of fast-refreshing in place.
57
- const componentRef = (0, react_1.useRef)(null);
58
- if ('component' in compProps) {
59
- componentRef.current = compProps.component;
60
+ const componentFromProps = 'component' in compProps
61
+ ? compProps.component
62
+ : null;
63
+ if (componentFromProps === undefined &&
64
+ typeof document !== 'undefined' &&
65
+ !noSuspense) {
66
+ throw new Error(`A value of \`undefined\` was passed to the \`component\` prop. Check the value you are passing to the <${componentName}/> component.`);
60
67
  }
68
+ const lazyComponentFromProps = 'lazyComponent' in compProps ? compProps.lazyComponent : null;
69
+ const componentStore = (0, react_1.useMemo)(() => (0, registry_store_js_1.createRegistryStore)(componentFromProps !== null && componentFromProps !== void 0 ? componentFromProps : null),
70
+ // A new lazy loader replaces the wrapper too. Component edits only update
71
+ // the existing store on commit, preserving the wrapper identity.
72
+ // eslint-disable-next-line react-hooks/exhaustive-deps
73
+ [lazyComponentFromProps]);
74
+ useIsomorphicLayoutEffect(() => {
75
+ if (componentFromProps !== null && componentFromProps !== undefined) {
76
+ componentStore.setSnapshot(() => componentFromProps);
77
+ }
78
+ }, [componentFromProps, componentStore]);
61
79
  const lazy = (0, react_1.useMemo)(() => {
62
80
  if ('component' in compProps) {
63
81
  // In SSR, suspense is not yet supported, we cannot use React.lazy
64
82
  if (typeof document === 'undefined' || noSuspense) {
65
83
  return compProps.component;
66
84
  }
67
- if (typeof compProps.component === 'undefined') {
68
- throw new Error(`A value of \`undefined\` was passed to the \`component\` prop. Check the value you are passing to the <${componentName}/> component.`);
69
- }
70
85
  const Wrapper = (props) => {
71
- const Comp = componentRef.current;
86
+ const Comp = (0, use_sync_external_store_js_1.useSyncExternalStore)(componentStore.subscribe, componentStore.getSnapshot, componentStore.getSnapshot);
72
87
  return react_1.default.createElement(Comp, props);
73
88
  };
74
89
  return Wrapper;
@@ -84,10 +99,9 @@ const useLazyComponent = ({ compProps, componentName, noSuspense, }) => {
84
99
  // Very important to leave the dependencies as they are, or instead
85
100
  // the player will remount on every frame.
86
101
  // For the 'component' case, we intentionally do NOT depend on
87
- // compProps.component — the stable wrapper reads from componentRef instead.
88
- // @ts-expect-error
102
+ // compProps.component — the stable wrapper subscribes to componentStore instead.
89
103
  // eslint-disable-next-line react-hooks/exhaustive-deps
90
- }, [compProps.lazyComponent]);
104
+ }, [lazyComponentFromProps, componentStore]);
91
105
  return lazy;
92
106
  };
93
107
  exports.useLazyComponent = useLazyComponent;
@@ -1,9 +1,5 @@
1
- import { type LoopVolumeCurveBehavior } from './audio/use-audio-frame.js';
2
- import type { LoopDisplay } from './CompositionManager.js';
3
- import type { VolumeProp } from './volume-prop.js';
4
- export declare const useBasicMediaInTimeline: ({ volume, mediaVolume, src, displayName, trimBefore, trimAfter, playbackRate, sequenceDurationInFrames, mediaStartsAt, mediaFrom, loop, muted, }: {
5
- volume: VolumeProp | undefined;
6
- mediaVolume: number;
1
+ import type { LoopDisplay, TSequence } from './CompositionManager.js';
2
+ export declare const useBasicMediaInTimeline: ({ src, displayName, trimBefore, trimAfter, playbackRate, sequenceDurationInFrames, mediaStartsAt, loop, muted, }: {
7
3
  src: string | undefined;
8
4
  displayName: string | null;
9
5
  trimBefore: number | undefined;
@@ -11,13 +7,10 @@ export declare const useBasicMediaInTimeline: ({ volume, mediaVolume, src, displ
11
7
  playbackRate: number;
12
8
  sequenceDurationInFrames: number;
13
9
  mediaStartsAt: number;
14
- mediaFrom: number;
15
10
  loop: boolean;
16
11
  muted: boolean;
17
12
  }) => {
18
- volumes: string | number;
19
13
  duration: number;
20
- doesVolumeChange: boolean;
21
14
  finalDisplayName: string;
22
15
  startMediaFrom: number;
23
16
  src: string;
@@ -25,9 +18,7 @@ export declare const useBasicMediaInTimeline: ({ volume, mediaVolume, src, displ
25
18
  muted: boolean;
26
19
  };
27
20
  export type BasicMediaInTimelineReturnType = ReturnType<typeof useBasicMediaInTimeline>;
28
- export declare const useMediaInTimeline: ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, id, getStack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, loopVolumeCurveBehavior, documentationLink, muted, }: {
29
- volume: VolumeProp | undefined;
30
- mediaVolume: number;
21
+ export declare const useMediaInTimelineRegistration: ({ src, mediaType, playbackRate, displayName, id, getStack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, documentationLink, muted, }: {
31
22
  src: string | undefined;
32
23
  mediaType: "audio" | "video";
33
24
  playbackRate: number;
@@ -38,7 +29,9 @@ export declare const useMediaInTimeline: ({ volume, mediaVolume, src, mediaType,
38
29
  premountDisplay: number | null;
39
30
  postmountDisplay: number | null;
40
31
  loopDisplay: LoopDisplay | undefined;
41
- loopVolumeCurveBehavior: LoopVolumeCurveBehavior;
42
32
  documentationLink: string | null;
43
33
  muted: boolean;
44
- }) => import("react").RefObject<Element | null> | null;
34
+ }) => {
35
+ automaticOutlineRef: import("react").RefObject<Element | null> | null;
36
+ registration: TSequence | null;
37
+ };