export interface IDisposable { dispose(): void; } export type DisposableItem = IDisposable | (() => void); export class DisposableBag implements IDisposable { private _disposables = new Set(); private _isDisposed = false; /** * Returns true if the bag has already been disposed. */ get isDisposed(): boolean { return this._isDisposed; } /** * Adds a disposable or a cleanup function to the bag. */ add(item: DisposableItem): void { if (this._isDisposed) { this._execute(item); return; } this._disposables.add(item); } /** * Disposes all items currently in the bag and clears the collection. */ dispose(): void { if (this._isDisposed) return; this._isDisposed = true; for (const item of this._disposables) { try { this._execute(item); } catch (error) { console.error("Error during resource disposal:", error); } } this._disposables.clear(); } private _execute(item: DisposableItem): void { if (typeof item === 'function') { item(); } else { item.dispose(); } } }