UNPKG

puppeteer-core

Version:

A high-level API to control headless Chrome over the DevTools Protocol

240 lines 8.4 kB
"use strict"; /** * @license * Copyright 2023 Google Inc. * SPDX-License-Identifier: Apache-2.0 */ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) { if (value !== null && value !== void 0) { if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); var dispose, inner; if (async) { if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); dispose = value[Symbol.asyncDispose]; } if (dispose === void 0) { if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); dispose = value[Symbol.dispose]; if (async) inner = dispose; } if (typeof dispose !== "function") throw new TypeError("Object not disposable."); if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; env.stack.push({ value: value, dispose: dispose, async: async }); } else if (async) { env.stack.push({ async: true }); } return value; }; var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) { return function (env) { function fail(e) { env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; env.hasError = true; } var r, s = 0; function next() { while (r = env.stack.pop()) { try { if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); if (r.dispose) { var result = r.dispose.call(r.value); if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); } else s |= 1; } catch (e) { fail(e); } } if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); if (env.hasError) throw env.error; } return next(); }; })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }); Object.defineProperty(exports, "__esModule", { value: true }); exports.moveable = moveable; exports.throwIfDisposed = throwIfDisposed; exports.inertIfDisposed = inertIfDisposed; exports.invokeAtMostOnceForArguments = invokeAtMostOnceForArguments; exports.guarded = guarded; exports.bubble = bubble; const disposable_js_1 = require("./disposable.js"); const Mutex_js_1 = require("./Mutex.js"); const instances = new WeakSet(); function moveable(Class, _) { let hasDispose = false; if (Class.prototype[disposable_js_1.disposeSymbol]) { const dispose = Class.prototype[disposable_js_1.disposeSymbol]; Class.prototype[disposable_js_1.disposeSymbol] = function () { if (instances.has(this)) { instances.delete(this); return; } return dispose.call(this); }; hasDispose = true; } if (Class.prototype[disposable_js_1.asyncDisposeSymbol]) { const asyncDispose = Class.prototype[disposable_js_1.asyncDisposeSymbol]; Class.prototype[disposable_js_1.asyncDisposeSymbol] = function () { if (instances.has(this)) { instances.delete(this); return; } return asyncDispose.call(this); }; hasDispose = true; } if (hasDispose) { Class.prototype.move = function () { instances.add(this); return this; }; } return Class; } function throwIfDisposed(message = value => { return `Attempted to use disposed ${value.constructor.name}.`; }) { return (target, _) => { return function (...args) { if (this.disposed) { throw new Error(message(this)); } return target.call(this, ...args); }; }; } function inertIfDisposed(target, _) { return function (...args) { if (this.disposed) { return; } return target.call(this, ...args); }; } /** * The decorator only invokes the target if the target has not been invoked with * the same arguments before. The decorated method throws an error if it's * invoked with a different number of elements: if you decorate a method, it * should have the same number of arguments * * @internal */ function invokeAtMostOnceForArguments(target, _) { const cache = new WeakMap(); let cacheDepth = -1; return function (...args) { if (cacheDepth === -1) { cacheDepth = args.length; } if (cacheDepth !== args.length) { throw new Error('Memoized method was called with the wrong number of arguments'); } let freshArguments = false; let cacheIterator = cache; for (const arg of args) { if (cacheIterator.has(arg)) { cacheIterator = cacheIterator.get(arg); } else { freshArguments = true; cacheIterator.set(arg, new WeakMap()); cacheIterator = cacheIterator.get(arg); } } if (!freshArguments) { return; } return target.call(this, ...args); }; } function guarded(getKey = function () { return this; }) { return (target, _) => { const mutexes = new WeakMap(); return async function (...args) { const env_1 = { stack: [], error: void 0, hasError: false }; try { const key = getKey.call(this); let mutex = mutexes.get(key); if (!mutex) { mutex = new Mutex_js_1.Mutex(); mutexes.set(key, mutex); } const _ = __addDisposableResource(env_1, await mutex.acquire(), true); return await target.call(this, ...args); } catch (e_1) { env_1.error = e_1; env_1.hasError = true; } finally { const result_1 = __disposeResources(env_1); if (result_1) await result_1; } }; }; } const bubbleHandlers = new WeakMap(); const bubbleInitializer = function (events) { const handlers = bubbleHandlers.get(this) ?? new Map(); if (handlers.has(events)) { return; } const handler = events !== undefined ? (type, event) => { if (events.includes(type)) { this.emit(type, event); } } : (type, event) => { this.emit(type, event); }; handlers.set(events, handler); bubbleHandlers.set(this, handlers); }; /** * Event emitter fields marked with `bubble` will have their events bubble up * the field owner. */ // The type is too complicated to type. function bubble(events) { return ({ set, get }, context) => { context.addInitializer(function () { return bubbleInitializer.apply(this, [events]); }); return { set(emitter) { const handler = bubbleHandlers.get(this).get(events); // In case we are re-setting. const oldEmitter = get.call(this); if (oldEmitter !== undefined) { oldEmitter.off('*', handler); } if (emitter === undefined) { return; } emitter.on('*', handler); set.call(this, emitter); }, init(emitter) { if (emitter === undefined) { return emitter; } bubbleInitializer.apply(this, [events]); const handler = bubbleHandlers.get(this).get(events); emitter.on('*', handler); return emitter; }, }; }; } //# sourceMappingURL=decorators.js.map