Skip to content

Commit bb1677e

Browse files
committed
Merge branch 'main' into jonny/split-sequence-props-tests
2 parents 597b876 + dad8e4d commit bb1677e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1056
-367
lines changed

packages/core/src/Composition.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ const InnerComposition = <
199199
defaultProps: serializeThenDeserializeInStudio(
200200
(defaultProps ?? {}) as z.output<Schema> & Props,
201201
) as InferProps<Schema, Props>,
202-
nonce,
202+
nonce: nonce.get(),
203203
parentFolderName: parentName,
204204
schema: schema ?? null,
205205
calculateMetadata: compProps.calculateMetadata ?? null,

packages/core/src/CompositionManager.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import type {AnyZodObject} from './any-zod-type.js';
44
import type {CalculateMetadataFunction} from './Composition.js';
55
import type {DownloadBehavior} from './download-behavior.js';
6+
import type {NonceHistory} from './nonce.js';
67
import type {InferProps, PropsIfHasProps} from './props-if-has-props.js';
78
import type {SequenceSchema} from './sequence-field-schema.js';
89

@@ -18,7 +19,7 @@ export type TComposition<
1819
folderName: string | null;
1920
parentFolderName: string | null;
2021
component: LazyExoticComponent<ComponentType<Props>> | ComponentType<Props>;
21-
nonce: number;
22+
nonce: NonceHistory;
2223
schema: Schema | null;
2324
calculateMetadata: CalculateMetadataFunction<
2425
InferProps<Schema, Props>
@@ -102,7 +103,7 @@ export type TSequence = {
102103
parent: string | null;
103104
rootId: string;
104105
showInTimeline: boolean;
105-
nonce: number;
106+
nonce: NonceHistory;
106107
loopDisplay: LoopDisplay | undefined;
107108
stack: string | null;
108109
premountDisplay: number | null;

packages/core/src/CompositionManagerContext.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {createContext} from 'react';
33
import type {AnyZodObject} from './any-zod-type.js';
44
import type {AnyComposition, TComposition} from './CompositionManager.js';
55
import type {TFolder} from './Folder.js';
6+
import type {NonceHistory} from './nonce.js';
67
import type {VideoConfig} from './video-config.js';
78

89
export type BaseMetadata = Pick<
@@ -49,7 +50,11 @@ export type CompositionManagerSetters = {
4950
comp: TComposition<Schema, Props>,
5051
) => void;
5152
unregisterComposition: (name: string) => void;
52-
registerFolder: (name: string, parent: string | null) => void;
53+
registerFolder: (
54+
name: string,
55+
parent: string | null,
56+
nonce: NonceHistory,
57+
) => void;
5358
unregisterFolder: (name: string, parent: string | null) => void;
5459
setCanvasContent: React.Dispatch<React.SetStateAction<CanvasContent | null>>;
5560
updateCompositionDefaultProps: (

packages/core/src/CompositionManagerProvider.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from './CompositionManagerContext';
2020
import type {BaseMetadata} from './CompositionManagerContext.js';
2121
import type {TFolder} from './Folder';
22+
import type {NonceHistory} from './nonce.js';
2223

2324
export const CompositionManagerProvider = ({
2425
children,
@@ -65,11 +66,7 @@ export const CompositionManagerProvider = ({
6566
);
6667
}
6768

68-
const value = [...comps, comp]
69-
.slice()
70-
71-
.sort((a, b) => a.nonce - b.nonce) as AnyComposition[];
72-
return value;
69+
return [...comps, comp] as AnyComposition[];
7370
});
7471
},
7572
[updateCompositions],
@@ -81,17 +78,21 @@ export const CompositionManagerProvider = ({
8178
});
8279
}, []);
8380

84-
const registerFolder = useCallback((name: string, parent: string | null) => {
85-
setFolders((prevFolders) => {
86-
return [
87-
...prevFolders,
88-
{
89-
name,
90-
parent,
91-
},
92-
];
93-
});
94-
}, []);
81+
const registerFolder = useCallback(
82+
(name: string, parent: string | null, nonce: NonceHistory) => {
83+
setFolders((prevFolders) => {
84+
return [
85+
...prevFolders,
86+
{
87+
name,
88+
parent,
89+
nonce,
90+
},
91+
];
92+
});
93+
},
94+
[],
95+
);
9596

9697
const unregisterFolder = useCallback(
9798
(name: string, parent: string | null) => {

packages/core/src/Folder.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import type {FC} from 'react';
22
import {createContext, useContext, useEffect, useMemo} from 'react';
33
import {CompositionSetters} from './CompositionManagerContext.js';
4+
import type {NonceHistory} from './nonce.js';
5+
import {useNonce} from './nonce.js';
46
import {truthy} from './truthy.js';
57
import {validateFolderName} from './validation/validate-folder-name.js';
68

79
export type TFolder = {
810
name: string;
911
parent: string | null;
12+
nonce: NonceHistory;
1013
};
1114

1215
type FolderContextType = {
@@ -29,6 +32,7 @@ export const Folder: FC<{
2932
}> = ({name, children}) => {
3033
const parent = useContext(FolderContext);
3134
const {registerFolder, unregisterFolder} = useContext(CompositionSetters);
35+
const nonce = useNonce();
3236

3337
validateFolderName(name);
3438

@@ -45,12 +49,19 @@ export const Folder: FC<{
4549
}, [name, parentName]);
4650

4751
useEffect(() => {
48-
registerFolder(name, parentName);
52+
registerFolder(name, parentName, nonce.get());
4953

5054
return () => {
5155
unregisterFolder(name, parentName);
5256
};
53-
}, [name, parent.folderName, parentName, registerFolder, unregisterFolder]);
57+
}, [
58+
name,
59+
parent.folderName,
60+
parentName,
61+
registerFolder,
62+
unregisterFolder,
63+
nonce,
64+
]);
5465

5566
return (
5667
<FolderContext.Provider value={value}>{children}</FolderContext.Provider>

packages/core/src/RemotionRoot.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export const RemotionRootContexts: React.FC<{
2121
readonly videoEnabled: boolean;
2222
readonly audioEnabled: boolean;
2323
readonly frameState: Record<string, number> | null;
24-
readonly nonceContextSeed: number;
2524
readonly visualModeEnabled: boolean;
2625
}> = ({
2726
children,
@@ -31,16 +30,14 @@ export const RemotionRootContexts: React.FC<{
3130
videoEnabled,
3231
audioEnabled,
3332
frameState,
34-
nonceContextSeed,
3533
visualModeEnabled,
3634
}) => {
3735
const nonceContext = useMemo((): TNonceContext => {
3836
let counter = 0;
3937
return {
4038
getNonce: () => counter++,
4139
};
42-
// eslint-disable-next-line react-hooks/exhaustive-deps
43-
}, [nonceContextSeed]);
40+
}, []);
4441

4542
const logging: LoggingContextValue = useMemo(() => {
4643
return {logLevel, mountTime: Date.now()};

packages/core/src/Sequence.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ const RegularSequenceRefForwardingFunction: React.ForwardRefRenderFunction<
223223
type: 'sequence',
224224
rootId,
225225
showInTimeline,
226-
nonce,
226+
nonce: nonce.get(),
227227
loopDisplay,
228228
stack: stack ?? inheritedStack,
229229
premountDisplay: premountDisplay ?? null,

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export {DownloadBehavior} from './download-behavior.js';
148148
export * from './easing.js';
149149
export * from './Folder.js';
150150
export * from './freeze.js';
151+
export type {NonceHistory} from './nonce.js';
151152
export {getRemotionEnvironment} from './get-remotion-environment.js';
152153
export {getStaticFiles, StaticFile} from './get-static-files.js';
153154
export * from './IFrame.js';

packages/core/src/internals.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import type {LoggingContextValue} from './log-level-context.js';
6363
import {LogLevelContext, useLogLevel} from './log-level-context.js';
6464
import {Log} from './log.js';
6565
import {MaxMediaCacheSizeContext} from './max-video-cache-size.js';
66+
import type {NonceHistory} from './nonce.js';
6667
import {NonceContext} from './nonce.js';
6768
import {playbackLogging} from './playback-logging.js';
6869
import {portalNode} from './portal-node.js';
@@ -301,4 +302,5 @@ export type {
301302
ScheduleAudioNodeOptions,
302303
CanUpdateSequencePropStatus,
303304
ScheduleAudioNodeResult,
305+
NonceHistory,
304306
};

packages/core/src/nonce.ts

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {createContext, useContext, useEffect, useRef, useState} from 'react';
1+
import {createContext, useCallback, useContext, useMemo, useRef} from 'react';
22

33
// Nonces keep track of the order of compositions.
44
// It's a counter that goes up and sequences and compositions get a nonce
@@ -11,25 +11,59 @@ export type TNonceContext = {
1111
getNonce: () => number;
1212
};
1313

14+
type NonceHistoryItem = [number, number];
15+
16+
export type NonceHistory = NonceHistoryItem[];
17+
18+
export type NonceHistoryContext = {
19+
get: () => NonceHistory;
20+
};
21+
1422
export const NonceContext = createContext<TNonceContext>({
1523
getNonce: () => 0,
1624
});
1725

18-
export const useNonce = (): number => {
19-
const context = useContext(NonceContext);
20-
const [nonce, setNonce] = useState(() => context.getNonce());
21-
const lastContext = useRef<TNonceContext | null>(context);
26+
let fastRefreshNonce = 0;
2227

23-
// Only if context changes, but not initially
24-
useEffect(() => {
25-
if (lastContext.current === context) {
26-
return;
28+
declare const __webpack_module__: {
29+
hot: {
30+
addStatusHandler(callback: (status: string) => void): void;
31+
};
32+
};
33+
34+
try {
35+
if (typeof __webpack_module__ !== 'undefined') {
36+
if (__webpack_module__.hot) {
37+
__webpack_module__.hot.addStatusHandler((status) => {
38+
if (status === 'idle') {
39+
fastRefreshNonce++;
40+
}
41+
});
2742
}
43+
}
44+
} catch {
45+
// __webpack_module__ may throw ReferenceError in some environments
46+
}
2847

29-
lastContext.current = context;
48+
export const useNonce = (): NonceHistoryContext => {
49+
const context = useContext(NonceContext);
50+
const nonce = context.getNonce();
51+
const nonceRef = useRef(nonce);
52+
nonceRef.current = nonce;
53+
const history = useRef<NonceHistoryItem[]>([[fastRefreshNonce, nonce]]);
54+
55+
const get = useCallback(() => {
56+
if (fastRefreshNonce !== history.current[history.current.length - 1][0]) {
57+
history.current = [
58+
...history.current,
59+
[fastRefreshNonce, nonceRef.current],
60+
];
61+
}
3062

31-
setNonce(context.getNonce);
32-
}, [context]);
63+
return history.current;
64+
}, [history]);
3365

34-
return nonce;
66+
return useMemo(() => {
67+
return {get};
68+
}, [get]);
3569
};

0 commit comments

Comments
 (0)