@remotion/web-renderer 4.0.374 → 4.0.375
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.
- package/dist/error-boundary.d.ts +16 -0
- package/dist/error-boundary.js +20 -0
- package/dist/esm/index.mjs +95 -64
- package/dist/render-still-on-web.d.ts +5 -4
- package/dist/render-still-on-web.js +61 -55
- package/dist/wait-for-ready.d.ts +1 -1
- package/dist/wait-for-ready.js +9 -2
- package/dist/with-resolvers.d.ts +10 -0
- package/dist/with-resolvers.js +9 -0
- package/package.json +4 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare class ErrorBoundary extends React.Component<{
|
|
3
|
+
onError: (error: Error) => void;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}, {
|
|
6
|
+
hasError: Error | null;
|
|
7
|
+
}> {
|
|
8
|
+
state: {
|
|
9
|
+
hasError: null;
|
|
10
|
+
};
|
|
11
|
+
static getDerivedStateFromError(): {
|
|
12
|
+
hasError: boolean;
|
|
13
|
+
};
|
|
14
|
+
componentDidCatch(error: Error): void;
|
|
15
|
+
render(): React.ReactNode;
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export class ErrorBoundary extends React.Component {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
this.state = { hasError: null };
|
|
6
|
+
}
|
|
7
|
+
static getDerivedStateFromError() {
|
|
8
|
+
// Update state so the next render will show the fallback UI.
|
|
9
|
+
return { hasError: true };
|
|
10
|
+
}
|
|
11
|
+
componentDidCatch(error) {
|
|
12
|
+
this.props.onError(error);
|
|
13
|
+
}
|
|
14
|
+
render() {
|
|
15
|
+
if (this.state.hasError) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return this.props.children;
|
|
19
|
+
}
|
|
20
|
+
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/render-still-on-web.tsx
|
|
2
|
+
import { flushSync } from "react-dom";
|
|
2
3
|
import ReactDOM from "react-dom/client";
|
|
3
4
|
import { Internals } from "remotion";
|
|
4
5
|
|
|
@@ -83,13 +84,29 @@ var findSvgElements = (element) => {
|
|
|
83
84
|
return composables;
|
|
84
85
|
};
|
|
85
86
|
|
|
87
|
+
// src/with-resolvers.ts
|
|
88
|
+
var withResolvers = function() {
|
|
89
|
+
let resolve;
|
|
90
|
+
let reject;
|
|
91
|
+
const promise = new Promise((res, rej) => {
|
|
92
|
+
resolve = res;
|
|
93
|
+
reject = rej;
|
|
94
|
+
});
|
|
95
|
+
return { promise, resolve, reject };
|
|
96
|
+
};
|
|
97
|
+
|
|
86
98
|
// src/wait-for-ready.ts
|
|
87
99
|
var waitForReady = (timeoutInMilliseconds, scope) => {
|
|
88
|
-
|
|
100
|
+
if (scope.remotion_renderReady === true) {
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
89
103
|
const start = Date.now();
|
|
104
|
+
const { promise, resolve, reject } = withResolvers();
|
|
90
105
|
const interval = setInterval(() => {
|
|
91
106
|
if (scope.remotion_renderReady === true) {
|
|
92
|
-
|
|
107
|
+
requestAnimationFrame(() => {
|
|
108
|
+
resolve();
|
|
109
|
+
});
|
|
93
110
|
clearInterval(interval);
|
|
94
111
|
return;
|
|
95
112
|
}
|
|
@@ -109,7 +126,7 @@ var waitForReady = (timeoutInMilliseconds, scope) => {
|
|
|
109
126
|
// src/render-still-on-web.tsx
|
|
110
127
|
import { jsx } from "react/jsx-runtime";
|
|
111
128
|
var COMP_ID = "markup";
|
|
112
|
-
|
|
129
|
+
async function internalRenderStillOnWeb({
|
|
113
130
|
Component,
|
|
114
131
|
width,
|
|
115
132
|
height,
|
|
@@ -117,8 +134,9 @@ var internalRenderStillOnWeb = async ({
|
|
|
117
134
|
durationInFrames,
|
|
118
135
|
frame,
|
|
119
136
|
delayRenderTimeoutInMilliseconds,
|
|
120
|
-
logLevel
|
|
121
|
-
|
|
137
|
+
logLevel,
|
|
138
|
+
inputProps
|
|
139
|
+
}) {
|
|
122
140
|
const div = document.createElement("div");
|
|
123
141
|
div.style.display = "flex";
|
|
124
142
|
div.style.backgroundColor = "transparent";
|
|
@@ -130,74 +148,87 @@ var internalRenderStillOnWeb = async ({
|
|
|
130
148
|
if (!ReactDOM.createRoot) {
|
|
131
149
|
throw new Error("@remotion/web-renderer requires React 18 or higher");
|
|
132
150
|
}
|
|
133
|
-
const
|
|
151
|
+
const { promise, resolve, reject } = withResolvers();
|
|
152
|
+
const root = ReactDOM.createRoot(div, {
|
|
153
|
+
onUncaughtError: (err) => {
|
|
154
|
+
reject(err);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
134
157
|
const delayRenderScope = {
|
|
135
158
|
remotion_renderReady: true,
|
|
136
159
|
remotion_delayRenderTimeouts: {},
|
|
137
160
|
remotion_puppeteerTimeout: delayRenderTimeoutInMilliseconds,
|
|
138
161
|
remotion_attempt: 0
|
|
139
162
|
};
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
videoEnabled: true,
|
|
187
|
-
logLevel,
|
|
188
|
-
numberOfAudioTags: 0,
|
|
189
|
-
audioLatencyHint: "interactive",
|
|
190
|
-
frameState: {
|
|
191
|
-
[COMP_ID]: frame
|
|
163
|
+
flushSync(() => {
|
|
164
|
+
root.render(/* @__PURE__ */ jsx(Internals.RemotionEnvironmentContext, {
|
|
165
|
+
value: {
|
|
166
|
+
isStudio: false,
|
|
167
|
+
isRendering: true,
|
|
168
|
+
isPlayer: false,
|
|
169
|
+
isReadOnlyStudio: false,
|
|
170
|
+
isClientSideRendering: true
|
|
171
|
+
},
|
|
172
|
+
children: /* @__PURE__ */ jsx(Internals.DelayRenderContextType.Provider, {
|
|
173
|
+
value: delayRenderScope,
|
|
174
|
+
children: /* @__PURE__ */ jsx(Internals.CompositionManager.Provider, {
|
|
175
|
+
value: {
|
|
176
|
+
compositions: [
|
|
177
|
+
{
|
|
178
|
+
id: COMP_ID,
|
|
179
|
+
component: Component,
|
|
180
|
+
nonce: 0,
|
|
181
|
+
defaultProps: undefined,
|
|
182
|
+
folderName: null,
|
|
183
|
+
parentFolderName: null,
|
|
184
|
+
schema: null,
|
|
185
|
+
calculateMetadata: null,
|
|
186
|
+
durationInFrames,
|
|
187
|
+
fps,
|
|
188
|
+
height,
|
|
189
|
+
width
|
|
190
|
+
}
|
|
191
|
+
],
|
|
192
|
+
canvasContent: {
|
|
193
|
+
type: "composition",
|
|
194
|
+
compositionId: COMP_ID
|
|
195
|
+
},
|
|
196
|
+
currentCompositionMetadata: {
|
|
197
|
+
props: inputProps,
|
|
198
|
+
durationInFrames,
|
|
199
|
+
fps,
|
|
200
|
+
height,
|
|
201
|
+
width,
|
|
202
|
+
defaultCodec: null,
|
|
203
|
+
defaultOutName: null,
|
|
204
|
+
defaultVideoImageFormat: null,
|
|
205
|
+
defaultPixelFormat: null,
|
|
206
|
+
defaultProResProfile: null
|
|
207
|
+
},
|
|
208
|
+
folders: []
|
|
192
209
|
},
|
|
193
|
-
children: /* @__PURE__ */ jsx(Internals.
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
children: /* @__PURE__ */ jsx(Internals.RemotionRoot, {
|
|
211
|
+
audioEnabled: false,
|
|
212
|
+
videoEnabled: true,
|
|
213
|
+
logLevel,
|
|
214
|
+
numberOfAudioTags: 0,
|
|
215
|
+
audioLatencyHint: "interactive",
|
|
216
|
+
frameState: {
|
|
217
|
+
[COMP_ID]: frame
|
|
218
|
+
},
|
|
219
|
+
children: /* @__PURE__ */ jsx(Internals.CanUseRemotionHooks, {
|
|
220
|
+
value: true,
|
|
221
|
+
children: /* @__PURE__ */ jsx(Component, {
|
|
222
|
+
...inputProps
|
|
223
|
+
})
|
|
224
|
+
})
|
|
196
225
|
})
|
|
197
226
|
})
|
|
198
227
|
})
|
|
199
|
-
})
|
|
200
|
-
})
|
|
228
|
+
}));
|
|
229
|
+
});
|
|
230
|
+
resolve();
|
|
231
|
+
await promise;
|
|
201
232
|
await waitForReady(delayRenderTimeoutInMilliseconds, delayRenderScope);
|
|
202
233
|
const canvasElements = findCanvasElements(div);
|
|
203
234
|
const svgElements = findSvgElements(div);
|
|
@@ -212,7 +243,7 @@ var internalRenderStillOnWeb = async ({
|
|
|
212
243
|
root.unmount();
|
|
213
244
|
div.remove();
|
|
214
245
|
return imageData;
|
|
215
|
-
}
|
|
246
|
+
}
|
|
216
247
|
var renderStillOnWeb = (options) => {
|
|
217
248
|
return internalRenderStillOnWeb({
|
|
218
249
|
...options,
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { type ComponentType, type LazyExoticComponent } from 'react';
|
|
2
2
|
import type { LogLevel } from 'remotion';
|
|
3
|
-
type MandatoryRenderStillOnWebOptions = {
|
|
4
|
-
Component: LazyExoticComponent<ComponentType<
|
|
3
|
+
type MandatoryRenderStillOnWebOptions<T extends Record<string, unknown>> = {
|
|
4
|
+
Component: LazyExoticComponent<ComponentType<T>> | ComponentType<T>;
|
|
5
5
|
width: number;
|
|
6
6
|
height: number;
|
|
7
7
|
fps: number;
|
|
8
8
|
durationInFrames: number;
|
|
9
9
|
frame: number;
|
|
10
|
+
inputProps: T;
|
|
10
11
|
};
|
|
11
12
|
type OptionalRenderStillOnWebOptions = {
|
|
12
13
|
delayRenderTimeoutInMilliseconds: number;
|
|
13
14
|
logLevel: LogLevel;
|
|
14
15
|
};
|
|
15
|
-
type RenderStillOnWebOptions = MandatoryRenderStillOnWebOptions & Partial<OptionalRenderStillOnWebOptions>;
|
|
16
|
-
export declare const renderStillOnWeb: (options: RenderStillOnWebOptions) => Promise<Blob>;
|
|
16
|
+
type RenderStillOnWebOptions<T extends Record<string, unknown>> = MandatoryRenderStillOnWebOptions<T> & Partial<OptionalRenderStillOnWebOptions>;
|
|
17
|
+
export declare const renderStillOnWeb: <T extends Record<string, unknown>>(options: RenderStillOnWebOptions<T>) => Promise<Blob>;
|
|
17
18
|
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { flushSync } from 'react-dom';
|
|
2
3
|
import ReactDOM from 'react-dom/client';
|
|
3
4
|
import { Internals } from 'remotion';
|
|
4
5
|
import { compose } from './compose';
|
|
5
6
|
import { findCanvasElements } from './find-canvas-elements';
|
|
6
7
|
import { findSvgElements } from './find-svg-elements';
|
|
7
8
|
import { waitForReady } from './wait-for-ready';
|
|
9
|
+
import { withResolvers } from './with-resolvers';
|
|
8
10
|
const COMP_ID = 'markup';
|
|
9
|
-
|
|
11
|
+
async function internalRenderStillOnWeb({ Component, width, height, fps, durationInFrames, frame, delayRenderTimeoutInMilliseconds, logLevel, inputProps, }) {
|
|
10
12
|
const div = document.createElement('div');
|
|
11
13
|
// Match same behavior as renderEntry.tsx
|
|
12
14
|
div.style.display = 'flex';
|
|
@@ -22,69 +24,73 @@ const internalRenderStillOnWeb = async ({ Component, width, height, fps, duratio
|
|
|
22
24
|
// TODO: Env variables
|
|
23
25
|
// TODO: Input Props
|
|
24
26
|
// TODO: Default props
|
|
27
|
+
// TODO: getInputProps()
|
|
25
28
|
// TODO: calculateMetadata()
|
|
26
29
|
// TODO: getRemotionEnvironment()
|
|
27
30
|
// TODO: delayRender()
|
|
28
31
|
// TODO: Video config
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
const { promise, resolve, reject } = withResolvers();
|
|
33
|
+
// TODO: This might not work in React 18
|
|
34
|
+
const root = ReactDOM.createRoot(div, {
|
|
35
|
+
onUncaughtError: (err) => {
|
|
36
|
+
reject(err);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
31
39
|
const delayRenderScope = {
|
|
32
40
|
remotion_renderReady: true,
|
|
33
41
|
remotion_delayRenderTimeouts: {},
|
|
34
42
|
remotion_puppeteerTimeout: delayRenderTimeoutInMilliseconds,
|
|
35
43
|
remotion_attempt: 0,
|
|
36
44
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
audioEnabled: false,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}, children: _jsx(Internals.CanUseRemotionHooks, { value: true, children: _jsx(Component, {}) }) }) }) }) }));
|
|
87
|
-
// TODO: Scope cancelRender()
|
|
45
|
+
flushSync(() => {
|
|
46
|
+
root.render(_jsx(Internals.RemotionEnvironmentContext, { value: {
|
|
47
|
+
isStudio: false,
|
|
48
|
+
isRendering: true,
|
|
49
|
+
isPlayer: false,
|
|
50
|
+
isReadOnlyStudio: false,
|
|
51
|
+
isClientSideRendering: true,
|
|
52
|
+
}, children: _jsx(Internals.DelayRenderContextType.Provider, { value: delayRenderScope, children: _jsx(Internals.CompositionManager.Provider, { value: {
|
|
53
|
+
compositions: [
|
|
54
|
+
{
|
|
55
|
+
id: COMP_ID,
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
component: Component,
|
|
58
|
+
nonce: 0,
|
|
59
|
+
// TODO: Do we need to allow to set this?
|
|
60
|
+
defaultProps: undefined,
|
|
61
|
+
folderName: null,
|
|
62
|
+
parentFolderName: null,
|
|
63
|
+
schema: null,
|
|
64
|
+
calculateMetadata: null,
|
|
65
|
+
durationInFrames,
|
|
66
|
+
fps,
|
|
67
|
+
height,
|
|
68
|
+
width,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
canvasContent: {
|
|
72
|
+
type: 'composition',
|
|
73
|
+
compositionId: COMP_ID,
|
|
74
|
+
},
|
|
75
|
+
currentCompositionMetadata: {
|
|
76
|
+
props: inputProps,
|
|
77
|
+
durationInFrames,
|
|
78
|
+
fps,
|
|
79
|
+
height,
|
|
80
|
+
width,
|
|
81
|
+
defaultCodec: null,
|
|
82
|
+
defaultOutName: null,
|
|
83
|
+
defaultVideoImageFormat: null,
|
|
84
|
+
defaultPixelFormat: null,
|
|
85
|
+
defaultProResProfile: null,
|
|
86
|
+
},
|
|
87
|
+
folders: [],
|
|
88
|
+
}, children: _jsx(Internals.RemotionRoot, { audioEnabled: false, videoEnabled: true, logLevel: logLevel, numberOfAudioTags: 0, audioLatencyHint: "interactive", frameState: {
|
|
89
|
+
[COMP_ID]: frame,
|
|
90
|
+
}, children: _jsx(Internals.CanUseRemotionHooks, { value: true, children: _jsx(Component, { ...inputProps }) }) }) }) }) }));
|
|
91
|
+
});
|
|
92
|
+
resolve();
|
|
93
|
+
await promise;
|
|
88
94
|
await waitForReady(delayRenderTimeoutInMilliseconds, delayRenderScope);
|
|
89
95
|
const canvasElements = findCanvasElements(div);
|
|
90
96
|
const svgElements = findSvgElements(div);
|
|
@@ -99,7 +105,7 @@ const internalRenderStillOnWeb = async ({ Component, width, height, fps, duratio
|
|
|
99
105
|
root.unmount();
|
|
100
106
|
div.remove();
|
|
101
107
|
return imageData;
|
|
102
|
-
}
|
|
108
|
+
}
|
|
103
109
|
export const renderStillOnWeb = (options) => {
|
|
104
110
|
var _a, _b;
|
|
105
111
|
return internalRenderStillOnWeb({
|
package/dist/wait-for-ready.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { _InternalTypes } from 'remotion';
|
|
2
|
-
export declare const waitForReady: (timeoutInMilliseconds: number, scope: _InternalTypes["DelayRenderScope"]) => Promise<
|
|
2
|
+
export declare const waitForReady: (timeoutInMilliseconds: number, scope: _InternalTypes["DelayRenderScope"]) => Promise<void>;
|
package/dist/wait-for-ready.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { withResolvers } from './with-resolvers';
|
|
1
2
|
export const waitForReady = (timeoutInMilliseconds, scope) => {
|
|
2
|
-
|
|
3
|
+
if (scope.remotion_renderReady === true) {
|
|
4
|
+
return Promise.resolve();
|
|
5
|
+
}
|
|
3
6
|
const start = Date.now();
|
|
7
|
+
const { promise, resolve, reject } = withResolvers();
|
|
4
8
|
const interval = setInterval(() => {
|
|
5
9
|
if (scope.remotion_renderReady === true) {
|
|
6
|
-
|
|
10
|
+
// Wait for useEffects() to apply
|
|
11
|
+
requestAnimationFrame(() => {
|
|
12
|
+
resolve();
|
|
13
|
+
});
|
|
7
14
|
clearInterval(interval);
|
|
8
15
|
return;
|
|
9
16
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface WithResolvers<T> {
|
|
2
|
+
promise: Promise<T>;
|
|
3
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
4
|
+
reject: (reason?: any) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const withResolvers: <T>() => {
|
|
7
|
+
promise: Promise<T>;
|
|
8
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
9
|
+
reject: (reason?: any) => void;
|
|
10
|
+
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/web-renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.375",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"scripts": {
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
"author": "Remotion <jonny@remotion.dev>",
|
|
16
16
|
"license": "UNLICENSED",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"remotion": "4.0.
|
|
18
|
+
"remotion": "4.0.375"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
21
|
+
"@remotion/eslint-config-internal": "4.0.375",
|
|
22
|
+
"@remotion/player": "4.0.375",
|
|
22
23
|
"@vitejs/plugin-react": "^5.1.0",
|
|
23
24
|
"@vitest/browser-webdriverio": "4.0.7",
|
|
24
25
|
"eslint": "9.19.0",
|