Files
simply_cpq/website/node_modules/@mui/x-internals/disposable/index.js
T
2026-08-07 21:39:30 +02:00

223 lines
7.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.disposeSymbol = exports.asyncDisposeSymbol = exports.DisposableStack = exports.AsyncDisposableStack = void 0;
exports.unwrapSuppressedErrors = unwrapSuppressedErrors;
/**
* Well-known `Symbol.dispose`. Resolves to the native well-known symbol when
* the runtime ships the explicit resource management proposal; otherwise falls
* back to `Symbol.for('Symbol.dispose')`, the same registry symbol used by the
* fallback stacks below, so `DisposableStack#use` finds the method.
*
* Consumers should key dispose methods on this constant —
* `class Foo { [disposeSymbol]() {} }` — rather than `Symbol.dispose`, so the
* class works on runtimes without the proposal.
*/
const disposeSymbol = exports.disposeSymbol = typeof Symbol.dispose === 'symbol' ? Symbol.dispose : Symbol.for('Symbol.dispose');
/**
* Well-known `Symbol.asyncDispose`. See {@link disposeSymbol} for the
* native/fallback resolution rules.
*/
const asyncDisposeSymbol = exports.asyncDisposeSymbol = typeof Symbol.asyncDispose === 'symbol' ? Symbol.asyncDispose : Symbol.for('Symbol.asyncDispose');
/** Object disposable via {@link disposeSymbol}. Mirrors `Disposable` from `esnext.disposable`. */
/** Object disposable via {@link asyncDisposeSymbol}. Mirrors `AsyncDisposable` from `esnext.disposable`. */
/**
* Mirrors the `DisposableStack` interface from `esnext.disposable`, declared
* locally so consumers don't need that lib in their TypeScript config.
*/
/**
* Mirrors the `AsyncDisposableStack` interface from `esnext.disposable`, declared
* locally so consumers don't need that lib in their TypeScript config.
*/
const NativeSuppressedError = typeof SuppressedError === 'function' ? SuppressedError : undefined;
/**
* Builds a `SuppressedError` (native when available, otherwise a compatible
* `{ error, suppressed }` Error) so {@link unwrapSuppressedErrors} can flatten
* the chain produced when several disposers throw.
*/
function createSuppressedError(error, suppressed) {
if (NativeSuppressedError) {
return new NativeSuppressedError(error, suppressed);
}
const wrapper = /* minify-error-disabled */new Error('An error was suppressed during disposal.');
return Object.assign(wrapper, {
name: 'SuppressedError',
error,
suppressed
});
}
function assertNotDisposed(disposed) {
if (disposed) {
throw /* minify-error-disabled */new ReferenceError('MUI X: The disposable stack is disposed.');
}
}
/**
* Minimal fallback for `DisposableStack`, used on runtimes that do not ship the
* explicit resource management proposal. Implements the subset of the proposal
* MUI X uses — `use`, `adopt`, `defer`, `move`, `dispose`, `disposed` and
* `[Symbol.dispose]` — so the `core-js-pure` ponyfill no longer has to be bundled.
*/
class FallbackDisposableStack {
stack = [];
isDisposed = false;
get disposed() {
return this.isDisposed;
}
use(value) {
assertNotDisposed(this.isDisposed);
if (value != null) {
const method = value[disposeSymbol];
if (typeof method !== 'function') {
throw /* minify-error-disabled */new TypeError('MUI X: The value is not disposable.');
}
this.stack.push(() => method.call(value));
}
return value;
}
adopt(value, onDispose) {
assertNotDisposed(this.isDisposed);
this.stack.push(() => onDispose(value));
return value;
}
defer(onDispose) {
assertNotDisposed(this.isDisposed);
this.stack.push(onDispose);
}
move() {
assertNotDisposed(this.isDisposed);
const next = new FallbackDisposableStack();
next.stack = this.stack;
this.stack = [];
this.isDisposed = true;
return next;
}
dispose() {
if (this.isDisposed) {
return;
}
this.isDisposed = true;
let hasError = false;
let error;
// Dispose in reverse (LIFO) order, aggregating failures into a SuppressedError chain.
for (let i = this.stack.length - 1; i >= 0; i -= 1) {
try {
this.stack[i]();
} catch (caught) {
error = hasError ? createSuppressedError(caught, error) : caught;
hasError = true;
}
}
this.stack = [];
if (hasError) {
throw error;
}
}
[disposeSymbol]() {
this.dispose();
}
}
/**
* Minimal fallback for `AsyncDisposableStack`. See {@link FallbackDisposableStack};
* disposers may return promises and are awaited sequentially in LIFO order.
*/
class FallbackAsyncDisposableStack {
stack = [];
isDisposed = false;
get disposed() {
return this.isDisposed;
}
use(value) {
assertNotDisposed(this.isDisposed);
if (value != null) {
const record = value;
const method = record[asyncDisposeSymbol] ?? record[disposeSymbol];
if (typeof method !== 'function') {
throw /* minify-error-disabled */new TypeError('MUI X: The value is not async disposable.');
}
this.stack.push(() => method.call(value));
}
return value;
}
adopt(value, onDisposeAsync) {
assertNotDisposed(this.isDisposed);
this.stack.push(() => onDisposeAsync(value));
return value;
}
defer(onDisposeAsync) {
assertNotDisposed(this.isDisposed);
this.stack.push(onDisposeAsync);
}
move() {
assertNotDisposed(this.isDisposed);
const next = new FallbackAsyncDisposableStack();
next.stack = this.stack;
this.stack = [];
this.isDisposed = true;
return next;
}
async disposeAsync() {
if (this.isDisposed) {
return;
}
this.isDisposed = true;
let hasError = false;
let error;
for (let i = this.stack.length - 1; i >= 0; i -= 1) {
try {
// eslint-disable-next-line no-await-in-loop
await this.stack[i]();
} catch (caught) {
error = hasError ? createSuppressedError(caught, error) : caught;
hasError = true;
}
}
this.stack = [];
if (hasError) {
throw error;
}
}
[asyncDisposeSymbol]() {
return this.disposeAsync();
}
}
/**
* Spec-compliant `DisposableStack`. Prefers the platform's native class when
* present; falls back to a minimal built-in implementation otherwise.
*/
// eslint-disable-next-line @typescript-eslint/no-redeclare
const DisposableStack = exports.DisposableStack = globalThis.DisposableStack ?? FallbackDisposableStack;
/**
* Spec-compliant `AsyncDisposableStack`. Prefers the platform's native class
* when present; falls back to a minimal built-in implementation otherwise.
*/
// eslint-disable-next-line @typescript-eslint/no-redeclare
const AsyncDisposableStack = exports.AsyncDisposableStack = globalThis.AsyncDisposableStack ?? FallbackAsyncDisposableStack;
/**
* Unwraps a `SuppressedError` chain (as produced by `DisposableStack.dispose()`
* when multiple disposers throw) into a flat list, outermost failure first.
* Returns `[error]` unchanged if it isn't a `SuppressedError`.
*/
function unwrapSuppressedErrors(error) {
const failures = [];
let current = error;
while (typeof current === 'object' && current !== null && 'error' in current && 'suppressed' in current) {
failures.push(current.error);
current = current.suppressed;
}
failures.push(current);
return failures;
}