/** * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved. * @license MIT * * Minimal lifecycle utilities for xterm.js core. * Simplified from VS Code's lifecycle.ts - no tracking/leak detection. */ export interface IDisposable { dispose(): void; } export function toDisposable(fn: () => void): IDisposable { return { dispose: fn }; } export function dispose(disposable: T): T; export function dispose(disposable: T | undefined): T | undefined; export function dispose(disposables: T[]): T[]; export function dispose(arg: T | T[] | undefined): T | T[] | undefined { if (!arg) { return arg; } if (Array.isArray(arg)) { for (const d of arg) { d.dispose(); } return []; } arg.dispose(); return arg; } export function combinedDisposable(...disposables: IDisposable[]): IDisposable { return toDisposable(() => dispose(disposables)); } export class DisposableStore implements IDisposable { private readonly _disposables = new Set(); private _isDisposed = false; public get isDisposed(): boolean { return this._isDisposed; } public add(o: T): T { if (this._isDisposed) { o.dispose(); } else { this._disposables.add(o); } return o; } public dispose(): void { if (this._isDisposed) { return; } this._isDisposed = true; for (const d of this._disposables) { d.dispose(); } this._disposables.clear(); } public clear(): void { for (const d of this._disposables) { d.dispose(); } this._disposables.clear(); } } export abstract class Disposable implements IDisposable { public static readonly None: IDisposable = Object.freeze({ dispose() { } }); protected readonly _store = new DisposableStore(); public dispose(): void { this._store.dispose(); } protected _register(o: T): T { return this._store.add(o); } } export class MutableDisposable implements IDisposable { private _value: T | undefined; private _isDisposed = false; public get value(): T | undefined { return this._isDisposed ? undefined : this._value; } public set value(value: T | undefined) { if (this._isDisposed || value === this._value) { return; } this._value?.dispose(); this._value = value; } public clear(): void { this.value = undefined; } public dispose(): void { this._isDisposed = true; this._value?.dispose(); this._value = undefined; } }