import { jsx as _jsx } from "react/jsx-runtime"; import { createRef } from 'react'; import { flushSync } from 'react-dom'; import ReactDOM from 'react-dom/client'; import { Internals } from 'remotion'; import { UpdateTime } from './update-time'; import { withResolvers } from './with-resolvers'; export async function createScaffold({ width, height, delayRenderTimeoutInMilliseconds, logLevel, resolvedProps, id, mediaCacheSizeInBytes, durationInFrames, fps, initialFrame, schema, Component, audioEnabled, videoEnabled, defaultCodec, defaultOutName, }) { if (!ReactDOM.createRoot) { throw new Error('@remotion/web-renderer requires React 18 or higher'); } const div = document.createElement('div'); // Match same behavior as in portal-node.ts div.style.position = 'fixed'; div.style.display = 'flex'; div.style.flexDirection = 'column'; div.style.backgroundColor = 'transparent'; div.style.width = `${width}px`; div.style.height = `${height}px`; div.style.zIndex = '-9999'; div.style.top = '0'; div.style.left = '0'; div.style.right = '0'; div.style.bottom = '0'; div.style.visibility = 'hidden'; div.style.pointerEvents = 'none'; const scaffoldClassName = `remotion-scaffold-${Math.random().toString(36).substring(2, 15)}`; div.className = scaffoldClassName; const cleanupCSS = Internals.CSSUtils.injectCSS(Internals.CSSUtils.makeDefaultPreviewCSS(`.${scaffoldClassName}`, 'white')); document.body.appendChild(div); const { promise, resolve, reject } = withResolvers(); // TODO: This might not work in React 18 const root = ReactDOM.createRoot(div, { onUncaughtError: (err) => { reject(err); }, }); const delayRenderScope = { remotion_renderReady: true, remotion_delayRenderTimeouts: {}, remotion_puppeteerTimeout: delayRenderTimeoutInMilliseconds, remotion_attempt: 0, remotion_delayRenderHandles: [], }; const timeUpdater = createRef(); const collectAssets = createRef(); flushSync(() => { root.render(_jsx(Internals.MaxMediaCacheSizeContext.Provider, { value: mediaCacheSizeInBytes, children: _jsx(Internals.RemotionEnvironmentContext.Provider, { value: { isStudio: false, isRendering: true, isPlayer: false, isReadOnlyStudio: false, isClientSideRendering: true, }, children: _jsx(Internals.DelayRenderContextType.Provider, { value: delayRenderScope, children: _jsx(Internals.CompositionManager.Provider, { value: { compositions: [ { id, // @ts-expect-error component: Component, nonce: 0, defaultProps: {}, folderName: null, parentFolderName: null, schema: schema !== null && schema !== void 0 ? schema : null, calculateMetadata: null, durationInFrames, fps, height, width, }, ], canvasContent: { type: 'composition', compositionId: id, }, currentCompositionMetadata: { props: resolvedProps, durationInFrames, fps, height, width, defaultCodec: defaultCodec !== null && defaultCodec !== void 0 ? defaultCodec : null, defaultOutName: defaultOutName !== null && defaultOutName !== void 0 ? defaultOutName : null, defaultVideoImageFormat: null, defaultPixelFormat: null, defaultProResProfile: null, }, folders: [], }, children: _jsx(Internals.RenderAssetManagerProvider, { collectAssets: collectAssets, children: _jsx(UpdateTime, { audioEnabled: audioEnabled, videoEnabled: videoEnabled, logLevel: logLevel, compId: id, initialFrame: initialFrame, timeUpdater: timeUpdater, children: _jsx(Internals.CanUseRemotionHooks.Provider, { value: true, children: _jsx(Component, { ...resolvedProps }) }) }) }) }) }) }) })); }); resolve(); await promise; return { delayRenderScope, div, cleanupScaffold: () => { root.unmount(); div.remove(); cleanupCSS(); }, timeUpdater, collectAssets, }; }