70 lines
2.2 KiB
JavaScript
70 lines
2.2 KiB
JavaScript
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
|
|
import { PonyfillSuppressedError } from './SupressedError.js';
|
|
import { DisposableSymbols } from './symbols.js';
|
|
import { isAsyncDisposable, isSyncDisposable } from './utils.js';
|
|
const SuppressedError = globalThis.SuppressedError || PonyfillSuppressedError;
|
|
export class PonyfillAsyncDisposableStack {
|
|
callbacks = [];
|
|
get disposed() {
|
|
return this.callbacks.length === 0;
|
|
}
|
|
use(value) {
|
|
if (isAsyncDisposable(value)) {
|
|
this.callbacks.push(() => value[DisposableSymbols.asyncDispose]());
|
|
}
|
|
else if (isSyncDisposable(value)) {
|
|
this.callbacks.push(() => value[DisposableSymbols.dispose]());
|
|
}
|
|
return value;
|
|
}
|
|
adopt(value, onDisposeAsync) {
|
|
if (onDisposeAsync) {
|
|
this.callbacks.push(() => onDisposeAsync(value));
|
|
}
|
|
return value;
|
|
}
|
|
defer(onDisposeAsync) {
|
|
if (onDisposeAsync) {
|
|
this.callbacks.push(onDisposeAsync);
|
|
}
|
|
}
|
|
move() {
|
|
const stack = new PonyfillAsyncDisposableStack();
|
|
stack.callbacks = this.callbacks;
|
|
this.callbacks = [];
|
|
return stack;
|
|
}
|
|
disposeAsync() {
|
|
return this[DisposableSymbols.asyncDispose]();
|
|
}
|
|
_error;
|
|
_iterateCallbacks() {
|
|
const cb = this.callbacks.pop();
|
|
if (cb) {
|
|
return handleMaybePromise(cb, () => this._iterateCallbacks(), error => {
|
|
this._error = this._error ? new SuppressedError(error, this._error) : error;
|
|
return this._iterateCallbacks();
|
|
});
|
|
}
|
|
}
|
|
[DisposableSymbols.asyncDispose]() {
|
|
const res$ = this._iterateCallbacks();
|
|
if (res$?.then) {
|
|
return res$.then(() => {
|
|
if (this._error) {
|
|
const error = this._error;
|
|
this._error = undefined;
|
|
throw error;
|
|
}
|
|
});
|
|
}
|
|
if (this._error) {
|
|
const error = this._error;
|
|
this._error = undefined;
|
|
throw error;
|
|
}
|
|
return undefined;
|
|
}
|
|
[Symbol.toStringTag] = 'AsyncDisposableStack';
|
|
}
|