Files
xterm.js/src/common/Lifecycle.ts
T
2026-02-01 22:22:29 -08:00

114 lines
2.6 KiB
TypeScript

/**
* 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<T extends IDisposable>(disposable: T): T;
export function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;
export function dispose<T extends IDisposable>(disposables: T[]): T[];
export function dispose<T extends IDisposable>(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<IDisposable>();
private _isDisposed = false;
public get isDisposed(): boolean {
return this._isDisposed;
}
public add<T extends IDisposable>(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<T extends IDisposable>(o: T): T {
return this._store.add(o);
}
}
export class MutableDisposable<T extends IDisposable> 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;
}
}