@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
163 lines (162 loc) • 6.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.puppeteerEvaluateWithCatchAndTimeout = puppeteerEvaluateWithCatchAndTimeout;
exports.puppeteerEvaluateWithCatch = puppeteerEvaluateWithCatch;
const JSHandle_1 = require("./browser/JSHandle");
const symbolicateable_error_1 = require("./error-handling/symbolicateable-error");
const parse_browser_error_stack_1 = require("./parse-browser-error-stack");
const EVALUATION_SCRIPT_URL = '__puppeteer_evaluation_script__';
function valueFromRemoteObject(remoteObject) {
if (remoteObject.unserializableValue) {
if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined')
return BigInt(remoteObject.unserializableValue.replace('n', ''));
switch (remoteObject.unserializableValue) {
case '-0':
return -0;
case 'NaN':
return NaN;
case 'Infinity':
return Infinity;
case '-Infinity':
return -Infinity;
default:
throw new Error('Unsupported unserializable value: ' +
remoteObject.unserializableValue);
}
}
return remoteObject.value;
}
function puppeteerEvaluateWithCatchAndTimeout({ args, frame, page, pageFunction, timeoutInMilliseconds, }) {
let timeout = null;
return Promise.race([
new Promise((_, reject) => {
timeout = setTimeout(() => {
reject(new Error(
// This means the page is not responding anymore
// This error message is retryable - sync it with packages/lambda/src/shared/is-flaky-error.ts
`Timed out evaluating page function "${pageFunction.toString()}"`));
}, timeoutInMilliseconds);
}),
puppeteerEvaluateWithCatch({
args,
frame,
page,
pageFunction,
timeoutInMilliseconds,
}),
]).then((data) => {
if (timeout !== null) {
clearTimeout(timeout);
}
return data;
});
}
async function puppeteerEvaluateWithCatch({ page, pageFunction, frame, args, }) {
var _a, _b, _c, _d, _e, _f;
const contextId = (await page.mainFrame().executionContext())._contextId;
const client = page._client();
const suffix = `//# sourceURL=${EVALUATION_SCRIPT_URL}`;
if (typeof pageFunction !== 'function')
throw new Error(`Expected to get |string| or |function| as the first argument, but got "${pageFunction}" instead.`);
let functionText = pageFunction.toString();
try {
// eslint-disable-next-line no-new-func
new Function('(' + functionText + ')');
}
catch (_g) {
// This means we might have a function shorthand. Try another
// time prefixing 'function '.
if (functionText.startsWith('async '))
functionText =
'async function ' + functionText.substring('async '.length);
else
functionText = 'function ' + functionText;
try {
// eslint-disable-next-line no-new-func
new Function('(' + functionText + ')');
}
catch (_h) {
// We tried hard to serialize, but there's a weird beast here.
throw new Error('Passed function is not well-serializable!');
}
}
let callFunctionOnPromise;
try {
callFunctionOnPromise = client.send('Runtime.callFunctionOn', {
functionDeclaration: functionText + '\n' + suffix + '\n',
executionContextId: contextId,
arguments: args.map((a) => convertArgument(a)),
returnByValue: true,
awaitPromise: true,
userGesture: true,
});
}
catch (error) {
if (error instanceof TypeError &&
error.message.startsWith('Converting circular structure to JSON')) {
error.message += ' Are you passing a nested JSHandle?';
}
throw error;
}
try {
const { value: { exceptionDetails, result: remoteObject }, size, } = await callFunctionOnPromise;
if (exceptionDetails) {
const err = new symbolicateable_error_1.SymbolicateableError({
stack: (_a = exceptionDetails.exception) === null || _a === void 0 ? void 0 : _a.description,
name: (_b = exceptionDetails.exception) === null || _b === void 0 ? void 0 : _b.className,
message: (_d = (_c = exceptionDetails.exception) === null || _c === void 0 ? void 0 : _c.description) === null || _d === void 0 ? void 0 : _d.split('\n')[0],
frame,
stackFrame: (0, parse_browser_error_stack_1.parseStack)(((_e = exceptionDetails.exception) === null || _e === void 0 ? void 0 : _e.description).split('\n')),
chunk: null,
});
page.close();
throw err;
}
return { size, value: valueFromRemoteObject(remoteObject) };
}
catch (error) {
if ((_f = error === null || error === void 0 ? void 0 : error.originalMessage) === null || _f === void 0 ? void 0 : _f.startsWith("Object couldn't be returned by value")) {
throw new Error('Could not serialize the return value of the function. Did you pass non-serializable values to defaultProps?');
}
throw error;
}
}
/**
* @param {*} arg
* @returns {*}
* @this {ExecutionContext}
*/
function convertArgument(arg) {
if (typeof arg === 'number') {
return { value: arg };
}
if (typeof arg === 'string') {
return { value: arg };
}
if (typeof arg === 'boolean') {
return { value: arg };
}
if (typeof arg === 'bigint')
return { unserializableValue: `${arg.toString()}n` };
if (Object.is(arg, -0))
return { unserializableValue: '-0' };
if (Object.is(arg, Infinity))
return { unserializableValue: 'Infinity' };
if (Object.is(arg, -Infinity))
return { unserializableValue: '-Infinity' };
if (Object.is(arg, NaN))
return { unserializableValue: 'NaN' };
const objectHandle = arg && arg instanceof JSHandle_1.JSHandle ? arg : null;
if (objectHandle) {
if (objectHandle._disposed)
throw new Error('JSHandle is disposed!');
if (objectHandle._remoteObject.unserializableValue)
return {
unserializableValue: objectHandle._remoteObject.unserializableValue,
};
if (!objectHandle._remoteObject.objectId)
return { value: objectHandle._remoteObject.value };
return { objectId: objectHandle._remoteObject.objectId };
}
return { value: arg };
}