UNPKG

@remotion/renderer

Version:

Render Remotion videos using Node.js or Bun

273 lines (272 loc) • 13.7 kB
"use strict"; /** * Copyright 2019 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _DOMWorld_frame, _DOMWorld_contextPromise, _DOMWorld_contextResolveCallback, _DOMWorld_detached, _DOMWorld_waitTasks, _WaitTask_instances, _WaitTask_domWorld, _WaitTask_timeout, _WaitTask_predicateBody, _WaitTask_args, _WaitTask_runCount, _WaitTask_resolve, _WaitTask_reject, _WaitTask_timeoutTimer, _WaitTask_terminated, _WaitTask_browser, _WaitTask_cleanup; Object.defineProperty(exports, "__esModule", { value: true }); exports.DOMWorld = void 0; const assert_1 = require("./assert"); const Errors_1 = require("./Errors"); const util_1 = require("./util"); class DOMWorld { get _waitTasks() { return __classPrivateFieldGet(this, _DOMWorld_waitTasks, "f"); } constructor(frame) { _DOMWorld_frame.set(this, void 0); _DOMWorld_contextPromise.set(this, null); _DOMWorld_contextResolveCallback.set(this, null); _DOMWorld_detached.set(this, false); _DOMWorld_waitTasks.set(this, new Set()); // Keep own reference to client because it might differ from the FrameManager's // client for OOP iframes. __classPrivateFieldSet(this, _DOMWorld_frame, frame, "f"); this._setContext(null); } frame() { return __classPrivateFieldGet(this, _DOMWorld_frame, "f"); } _setContext(context) { var _a; if (context) { (0, assert_1.assert)(__classPrivateFieldGet(this, _DOMWorld_contextResolveCallback, "f"), 'Execution Context has already been set.'); (_a = __classPrivateFieldGet(this, _DOMWorld_contextResolveCallback, "f")) === null || _a === void 0 ? void 0 : _a.call(null, context); __classPrivateFieldSet(this, _DOMWorld_contextResolveCallback, null, "f"); for (const waitTask of this._waitTasks) { waitTask.rerun(); } } else { __classPrivateFieldSet(this, _DOMWorld_contextPromise, new Promise((fulfill) => { __classPrivateFieldSet(this, _DOMWorld_contextResolveCallback, fulfill, "f"); }), "f"); } } _hasContext() { return !__classPrivateFieldGet(this, _DOMWorld_contextResolveCallback, "f"); } _detach() { __classPrivateFieldSet(this, _DOMWorld_detached, true, "f"); for (const waitTask of this._waitTasks) { waitTask.terminate(new Error('waitForFunction failed: frame got detached.')); } } executionContext() { if (__classPrivateFieldGet(this, _DOMWorld_detached, "f")) { throw new Error(`Execution context is not available in detached frame "${__classPrivateFieldGet(this, _DOMWorld_frame, "f").url()}" (are you trying to evaluate?)`); } if (__classPrivateFieldGet(this, _DOMWorld_contextPromise, "f") === null) { throw new Error(`Execution content promise is missing`); } return __classPrivateFieldGet(this, _DOMWorld_contextPromise, "f"); } async evaluateHandle(pageFunction, ...args) { const context = await this.executionContext(); return context.evaluateHandle(pageFunction, ...args); } async evaluate(pageFunction, ...args) { const context = await this.executionContext(); return context.evaluate(pageFunction, ...args); } waitForFunction({ browser, timeout, pageFunction, title, }) { return new WaitTask({ domWorld: this, predicateBody: pageFunction, title, timeout, args: [], browser, }); } } exports.DOMWorld = DOMWorld; _DOMWorld_frame = new WeakMap(), _DOMWorld_contextPromise = new WeakMap(), _DOMWorld_contextResolveCallback = new WeakMap(), _DOMWorld_detached = new WeakMap(), _DOMWorld_waitTasks = new WeakMap(); const noop = () => undefined; class WaitTask { constructor(options) { _WaitTask_instances.add(this); _WaitTask_domWorld.set(this, void 0); _WaitTask_timeout.set(this, void 0); _WaitTask_predicateBody.set(this, void 0); _WaitTask_args.set(this, void 0); _WaitTask_runCount.set(this, 0); _WaitTask_resolve.set(this, noop); _WaitTask_reject.set(this, noop); _WaitTask_timeoutTimer.set(this, void 0); _WaitTask_terminated.set(this, false); _WaitTask_browser.set(this, void 0); this.onBrowserClose = () => { return this.terminate(new Error('Browser was closed')); }; this.onBrowserCloseSilent = () => { return this.terminate(null); }; function getPredicateBody(predicateBody) { if ((0, util_1.isString)(predicateBody)) { return `return (${predicateBody});`; } return `return (${predicateBody})(...args);`; } __classPrivateFieldSet(this, _WaitTask_domWorld, options.domWorld, "f"); __classPrivateFieldSet(this, _WaitTask_timeout, options.timeout, "f"); __classPrivateFieldSet(this, _WaitTask_predicateBody, getPredicateBody(options.predicateBody), "f"); __classPrivateFieldSet(this, _WaitTask_args, options.args, "f"); __classPrivateFieldSet(this, _WaitTask_runCount, 0, "f"); __classPrivateFieldGet(this, _WaitTask_domWorld, "f")._waitTasks.add(this); this.promise = new Promise((resolve, reject) => { __classPrivateFieldSet(this, _WaitTask_resolve, resolve, "f"); __classPrivateFieldSet(this, _WaitTask_reject, reject, "f"); }); // Since page navigation requires us to re-install the pageScript, we should track // timeout on our end. if (options.timeout) { const timeoutError = new Errors_1.TimeoutError(`waiting for ${options.title} failed: timeout ${options.timeout}ms exceeded`); __classPrivateFieldSet(this, _WaitTask_timeoutTimer, setTimeout(() => { return __classPrivateFieldGet(this, _WaitTask_reject, "f").call(this, timeoutError); }, options.timeout), "f"); } __classPrivateFieldSet(this, _WaitTask_browser, options.browser, "f"); __classPrivateFieldGet(this, _WaitTask_browser, "f").on("closed" /* BrowserEmittedEvents.Closed */, this.onBrowserClose); __classPrivateFieldGet(this, _WaitTask_browser, "f").on("closed-silent" /* BrowserEmittedEvents.ClosedSilent */, this.onBrowserCloseSilent); this.rerun(); } terminate(error) { __classPrivateFieldSet(this, _WaitTask_terminated, true, "f"); if (error) { __classPrivateFieldGet(this, _WaitTask_reject, "f").call(this, error); } __classPrivateFieldGet(this, _WaitTask_instances, "m", _WaitTask_cleanup).call(this); } async rerun() { var _a; const runCount = __classPrivateFieldSet(this, _WaitTask_runCount, (_a = __classPrivateFieldGet(this, _WaitTask_runCount, "f"), ++_a), "f"); let success = null; let error = null; const context = await __classPrivateFieldGet(this, _WaitTask_domWorld, "f").executionContext(); if (__classPrivateFieldGet(this, _WaitTask_terminated, "f") || runCount !== __classPrivateFieldGet(this, _WaitTask_runCount, "f")) { return; } if (__classPrivateFieldGet(this, _WaitTask_terminated, "f") || runCount !== __classPrivateFieldGet(this, _WaitTask_runCount, "f")) { return; } try { success = await context.evaluateHandle(waitForPredicatePageFunction, __classPrivateFieldGet(this, _WaitTask_predicateBody, "f"), __classPrivateFieldGet(this, _WaitTask_timeout, "f"), ...__classPrivateFieldGet(this, _WaitTask_args, "f")); } catch (error_) { error = error_; } if (__classPrivateFieldGet(this, _WaitTask_terminated, "f") || runCount !== __classPrivateFieldGet(this, _WaitTask_runCount, "f")) { if (success) { await success.dispose(); } return; } // Ignore timeouts in pageScript - we track timeouts ourselves. // If the frame's execution context has already changed, `frame.evaluate` will // throw an error - ignore this predicate run altogether. if (!error && (await __classPrivateFieldGet(this, _WaitTask_domWorld, "f") .evaluate((s) => { return !s; }, success) .catch(() => { return true; }))) { if (!success) { throw new Error('Assertion: result handle is not available'); } await success.dispose(); return; } if (error) { if (error.message.includes('TypeError: binding is not a function')) { return this.rerun(); } // When frame is detached the task should have been terminated by the DOMWorld. // This can fail if we were adding this task while the frame was detached, // so we terminate here instead. if (error.message.includes('Execution context is not available in detached frame')) { this.terminate(new Error('waitForFunction failed: frame got detached.')); return; } // When the page is navigated, the promise is rejected. // We will try again in the new execution context. if (error.message.includes('Execution context was destroyed')) { return; } // We could have tried to evaluate in a context which was already // destroyed. if (error.message.includes('Cannot find context with specified id')) { return; } __classPrivateFieldGet(this, _WaitTask_reject, "f").call(this, error); } else { if (!success) { throw new Error('Assertion: result handle is not available'); } __classPrivateFieldGet(this, _WaitTask_resolve, "f").call(this, success); } __classPrivateFieldGet(this, _WaitTask_instances, "m", _WaitTask_cleanup).call(this); } } _WaitTask_domWorld = new WeakMap(), _WaitTask_timeout = new WeakMap(), _WaitTask_predicateBody = new WeakMap(), _WaitTask_args = new WeakMap(), _WaitTask_runCount = new WeakMap(), _WaitTask_resolve = new WeakMap(), _WaitTask_reject = new WeakMap(), _WaitTask_timeoutTimer = new WeakMap(), _WaitTask_terminated = new WeakMap(), _WaitTask_browser = new WeakMap(), _WaitTask_instances = new WeakSet(), _WaitTask_cleanup = function _WaitTask_cleanup() { if (__classPrivateFieldGet(this, _WaitTask_timeoutTimer, "f") !== undefined) { clearTimeout(__classPrivateFieldGet(this, _WaitTask_timeoutTimer, "f")); } __classPrivateFieldGet(this, _WaitTask_browser, "f").off("closed" /* BrowserEmittedEvents.Closed */, this.onBrowserClose); __classPrivateFieldGet(this, _WaitTask_browser, "f").off("closed-silent" /* BrowserEmittedEvents.ClosedSilent */, this.onBrowserCloseSilent); if (__classPrivateFieldGet(this, _WaitTask_domWorld, "f")._waitTasks.size > 100) { throw new Error('Leak detected: Too many WaitTasks'); } __classPrivateFieldGet(this, _WaitTask_domWorld, "f")._waitTasks.delete(this); }; function waitForPredicatePageFunction(predicateBody, timeout, ...args) { // eslint-disable-next-line no-new-func const predicate = new Function('...args', predicateBody); let timedOut = false; if (timeout) { setTimeout(() => { timedOut = true; }, timeout); } return new Promise((resolve) => { async function onRaf() { if (timedOut) { resolve(undefined); return; } const success = await predicate(...args); if (success) { resolve(success); } else { requestAnimationFrame(onRaf); } } onRaf(); }); }