Update dashboard, kb, memory +4 more (+28 ~18 -1)
This commit is contained in:
396
node_modules/puppeteer-core/src/util/disposable.ts
generated
vendored
Normal file
396
node_modules/puppeteer-core/src/util/disposable.ts
generated
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
declare global {
|
||||
interface SymbolConstructor {
|
||||
/**
|
||||
* A method that is used to release resources held by an object. Called by
|
||||
* the semantics of the `using` statement.
|
||||
*/
|
||||
readonly dispose: unique symbol;
|
||||
|
||||
/**
|
||||
* A method that is used to asynchronously release resources held by an
|
||||
* object. Called by the semantics of the `await using` statement.
|
||||
*/
|
||||
readonly asyncDispose: unique symbol;
|
||||
}
|
||||
|
||||
interface Disposable {
|
||||
[Symbol.dispose](): void;
|
||||
}
|
||||
|
||||
interface AsyncDisposable {
|
||||
[Symbol.asyncDispose](): PromiseLike<void>;
|
||||
}
|
||||
}
|
||||
|
||||
(Symbol as any).dispose ??= Symbol('dispose');
|
||||
(Symbol as any).asyncDispose ??= Symbol('asyncDispose');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const disposeSymbol: typeof Symbol.dispose = Symbol.dispose;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const asyncDisposeSymbol: typeof Symbol.asyncDispose =
|
||||
Symbol.asyncDispose;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class DisposableStackPolyfill {
|
||||
#disposed = false;
|
||||
#stack: Disposable[] = [];
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether the stack has been disposed.
|
||||
*/
|
||||
get disposed(): boolean {
|
||||
return this.#disposed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for `[Symbol.dispose]()`.
|
||||
*/
|
||||
dispose(): void {
|
||||
this[disposeSymbol]();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a disposable resource to the top of stack, returning the resource.
|
||||
* Has no effect if provided `null` or `undefined`.
|
||||
*
|
||||
* @param value - A `Disposable` object, `null`, or `undefined`.
|
||||
* `null` and `undefined` will not be added, but will be returned.
|
||||
* @returns The provided `value`.
|
||||
*/
|
||||
use<T extends Disposable | null | undefined>(value: T): T {
|
||||
if (value && typeof value[disposeSymbol] === 'function') {
|
||||
this.#stack.push(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a non-disposable resource and a disposal callback to the top of the stack.
|
||||
*
|
||||
* @param value - A resource to be disposed.
|
||||
* @param onDispose - A callback invoked to dispose the provided value.
|
||||
* Will be invoked with `value` as the first parameter.
|
||||
* @returns The provided `value`.
|
||||
*/
|
||||
adopt<T>(value: T, onDispose: (value: T) => void): T {
|
||||
this.#stack.push({
|
||||
[disposeSymbol]() {
|
||||
onDispose(value);
|
||||
},
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a disposal callback to the top of the stack to be invoked when stack is disposed.
|
||||
* @param onDispose - A callback to invoke when this object is disposed.
|
||||
*/
|
||||
defer(onDispose: () => void): void {
|
||||
this.#stack.push({
|
||||
[disposeSymbol]() {
|
||||
onDispose();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all resources out of this stack and into a new `DisposableStack`, and
|
||||
* marks this stack as disposed.
|
||||
* @returns The new `DisposableStack`.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* class C {
|
||||
* #res1: Disposable;
|
||||
* #res2: Disposable;
|
||||
* #disposables: DisposableStack;
|
||||
* constructor() {
|
||||
* // stack will be disposed when exiting constructor for any reason
|
||||
* using stack = new DisposableStack();
|
||||
*
|
||||
* // get first resource
|
||||
* this.#res1 = stack.use(getResource1());
|
||||
*
|
||||
* // get second resource. If this fails, both `stack` and `#res1` will be disposed.
|
||||
* this.#res2 = stack.use(getResource2());
|
||||
*
|
||||
* // all operations succeeded, move resources out of `stack` so that
|
||||
* // they aren't disposed when constructor exits
|
||||
* this.#disposables = stack.move();
|
||||
* }
|
||||
*
|
||||
* [disposeSymbol]() {
|
||||
* this.#disposables.dispose();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
move(): DisposableStackPolyfill {
|
||||
if (this.#disposed) {
|
||||
throw new ReferenceError('A disposed stack can not use anything new');
|
||||
}
|
||||
const stack = new DisposableStackPolyfill();
|
||||
stack.#stack = this.#stack;
|
||||
this.#stack = [];
|
||||
this.#disposed = true;
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes each resource in the stack in last-in-first-out (LIFO) manner.
|
||||
*/
|
||||
[disposeSymbol](): void {
|
||||
if (this.#disposed) {
|
||||
return;
|
||||
}
|
||||
this.#disposed = true;
|
||||
const errors: unknown[] = [];
|
||||
for (const resource of this.#stack.reverse()) {
|
||||
try {
|
||||
resource[disposeSymbol]();
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
if (errors.length === 1) {
|
||||
throw errors[0];
|
||||
} else if (errors.length > 1) {
|
||||
let suppressed = null;
|
||||
for (const error of errors) {
|
||||
if (suppressed === null) {
|
||||
suppressed = error;
|
||||
} else {
|
||||
suppressed = new SuppressedErrorPolyfill(error, suppressed);
|
||||
}
|
||||
}
|
||||
throw suppressed;
|
||||
}
|
||||
}
|
||||
|
||||
readonly [Symbol.toStringTag] = 'DisposableStack';
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const DisposableStack: typeof DisposableStackPolyfill =
|
||||
(globalThis.DisposableStack as any) ?? DisposableStackPolyfill;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class AsyncDisposableStackPolyfill {
|
||||
#disposed = false;
|
||||
#stack: AsyncDisposable[] = [];
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether the stack has been disposed.
|
||||
*/
|
||||
get disposed(): boolean {
|
||||
return this.#disposed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for `[Symbol.asyncDispose]()`.
|
||||
*/
|
||||
async disposeAsync(): Promise<void> {
|
||||
await this[asyncDisposeSymbol]();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a AsyncDisposable resource to the top of stack, returning the resource.
|
||||
* Has no effect if provided `null` or `undefined`.
|
||||
*
|
||||
* @param value - A `AsyncDisposable` object, `null`, or `undefined`.
|
||||
* `null` and `undefined` will not be added, but will be returned.
|
||||
* @returns The provided `value`.
|
||||
*/
|
||||
use<T extends AsyncDisposable | Disposable | null | undefined>(value: T): T {
|
||||
if (value) {
|
||||
const asyncDispose = (value as AsyncDisposable)[asyncDisposeSymbol];
|
||||
const dispose = (value as Disposable)[disposeSymbol];
|
||||
|
||||
if (typeof asyncDispose === 'function') {
|
||||
this.#stack.push(value as AsyncDisposable);
|
||||
} else if (typeof dispose === 'function') {
|
||||
this.#stack.push({
|
||||
[asyncDisposeSymbol]: async () => {
|
||||
(value as Disposable)[disposeSymbol]();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a non-disposable resource and a disposal callback to the top of the stack.
|
||||
*
|
||||
* @param value - A resource to be disposed.
|
||||
* @param onDispose - A callback invoked to dispose the provided value.
|
||||
* Will be invoked with `value` as the first parameter.
|
||||
* @returns The provided `value`.
|
||||
*/
|
||||
adopt<T>(value: T, onDispose: (value: T) => Promise<void>): T {
|
||||
this.#stack.push({
|
||||
[asyncDisposeSymbol]() {
|
||||
return onDispose(value);
|
||||
},
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a disposal callback to the top of the stack to be invoked when stack is disposed.
|
||||
* @param onDispose - A callback to invoke when this object is disposed.
|
||||
*/
|
||||
defer(onDispose: () => Promise<void>): void {
|
||||
this.#stack.push({
|
||||
[asyncDisposeSymbol]() {
|
||||
return onDispose();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all resources out of this stack and into a new `DisposableStack`, and
|
||||
* marks this stack as disposed.
|
||||
* @returns The new `AsyncDisposableStack`.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* class C {
|
||||
* #res1: Disposable;
|
||||
* #res2: Disposable;
|
||||
* #disposables: DisposableStack;
|
||||
* constructor() {
|
||||
* // stack will be disposed when exiting constructor for any reason
|
||||
* using stack = new DisposableStack();
|
||||
*
|
||||
* // get first resource
|
||||
* this.#res1 = stack.use(getResource1());
|
||||
*
|
||||
* // get second resource. If this fails, both `stack` and `#res1` will be disposed.
|
||||
* this.#res2 = stack.use(getResource2());
|
||||
*
|
||||
* // all operations succeeded, move resources out of `stack` so that
|
||||
* // they aren't disposed when constructor exits
|
||||
* this.#disposables = stack.move();
|
||||
* }
|
||||
*
|
||||
* [disposeSymbol]() {
|
||||
* this.#disposables.dispose();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
move(): AsyncDisposableStackPolyfill {
|
||||
if (this.#disposed) {
|
||||
throw new ReferenceError('A disposed stack can not use anything new');
|
||||
}
|
||||
const stack = new AsyncDisposableStackPolyfill();
|
||||
stack.#stack = this.#stack;
|
||||
this.#stack = [];
|
||||
this.#disposed = true;
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes each resource in the stack in last-in-first-out (LIFO) manner.
|
||||
*/
|
||||
async [asyncDisposeSymbol](): Promise<void> {
|
||||
if (this.#disposed) {
|
||||
return;
|
||||
}
|
||||
this.#disposed = true;
|
||||
const errors: unknown[] = [];
|
||||
for (const resource of this.#stack.reverse()) {
|
||||
try {
|
||||
await resource[asyncDisposeSymbol]();
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
if (errors.length === 1) {
|
||||
throw errors[0];
|
||||
} else if (errors.length > 1) {
|
||||
let suppressed = null;
|
||||
for (const error of errors) {
|
||||
if (suppressed === null) {
|
||||
suppressed = error;
|
||||
} else {
|
||||
suppressed = new SuppressedErrorPolyfill(error, suppressed);
|
||||
}
|
||||
}
|
||||
throw suppressed;
|
||||
}
|
||||
}
|
||||
|
||||
readonly [Symbol.toStringTag] = 'AsyncDisposableStack';
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const AsyncDisposableStack: typeof AsyncDisposableStackPolyfill =
|
||||
(globalThis.AsyncDisposableStack as any) ?? AsyncDisposableStackPolyfill;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Represents an error that occurs when multiple errors are thrown during
|
||||
* the disposal of resources. This class encapsulates the primary error and
|
||||
* any suppressed errors that occurred subsequently.
|
||||
*/
|
||||
class SuppressedErrorPolyfill extends Error {
|
||||
#error: unknown;
|
||||
#suppressed: unknown;
|
||||
|
||||
constructor(
|
||||
error: unknown,
|
||||
suppressed: unknown,
|
||||
message = 'An error was suppressed during disposal',
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'SuppressedError';
|
||||
this.#error = error;
|
||||
this.#suppressed = suppressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* The primary error that occurred during disposal.
|
||||
*/
|
||||
get error(): unknown {
|
||||
return this.#error;
|
||||
}
|
||||
|
||||
/**
|
||||
* The suppressed error i.e. the error that was suppressed
|
||||
* because it occurred later in the flow after the original error.
|
||||
*/
|
||||
get suppressed(): unknown {
|
||||
return this.#suppressed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const SuppressedError: typeof SuppressedErrorPolyfill =
|
||||
(globalThis.SuppressedError as any) ?? SuppressedErrorPolyfill;
|
||||
Reference in New Issue
Block a user